Telerik OpenAccess Classic

Telerik OpenAccess ORM Send comments on this topic.
Defining FetchGroups
See Also
Programmer's Guide > OpenAccess ORM Classic (Old API) > Programming With OpenAccess > FetchPlans and FetchGroups > Defining FetchGroups

Glossary Item Box

This documentation article is a legacy resource describing the functionality of the deprecated OpenAccess Classic only. The contemporary documentation of Telerik OpenAccess ORM is available here.

FetchGroups can be defined, by using the Fetch Group Tab tab page of the Forward Mapping Wizard, which defines the fetchgroups either by XML entries in the App.config file or by using the FetchField attribute in the source code. During runtime both these ways are handled equivalently.

Use the Options Dialog to specify the location of the fetchgroup definition. By default the fetchgroup definition is written to the source code.

The settings specified in the Options Dialog would be applicable only for new entries, i.e., only when you make any change to the fetchgroup definition will the entries for that particular fetchgroup be made as per your settings. For e.g., if you have defined two fetchgroups, FG_Name and FG_Address and you want to move your entries from the source code to the XML file. First you have to make the appropriate choice in the Options Dialog, then if you make some change to the FG_Name fetchgroup, only the definition for the FG_Name fetchgroup will be moved to the App.config file. The definition for the FG_Address fetchgroup will be moved to the App.config file, only when you make changes to it.

The [FetchField] attribute is used to mark fields to be included in the named FetchGroup. For example

C# Copy Code
[Persistent]
public abstract class Employee
{
   
private int empNo;
   [FetchField(
"FG_empName" )]
   
private string firstname;
   [FetchField(
"FG_empName" )]
   
private string lastname;
}
VB .NET Copy Code
<Persistent> _
Public MustInherit Class Employee
 Private empNo As Integer
 <FetchField("FG_empName")> _
 Private firstname As String
 <FetchField("FG_empName")> _
 Private lastname As String
End Class

As shown in the example above, the [FetchField] attribute has been used to mark the lastname and firstname fields. This means that, these fields will part of the named FetchGroup, "FG_empName" and will be loaded, along with the object, when it is initially retrieved from the database, as a result of a query or while resolving a reference.

The corresponding XML entry used to define the "FG_empName" fetchgroup is given below:

XML Copy Code
<class name="Employee">
 
<fetch-group name="FG_empName">
   
<field name="firstname"/>
   
<field name="lastname"/>
 
</fetch-group>
</
class>

Using the User-Interface

The class level user-interface of the mapping dialog contains the Fetch Group Tab in the Forward Mapping Wizard, which is used to define fetchgroups. Fetchgroups can be defined in either the source code using the FetchField Attribute or by writing appropriate XML entries to the application configuration file, i.e., the App.config file. Use the Options Dialog to specify the location of the fetchgroup definition. By default the fetchgroup definition is written to the source code.

Similarly any changes or updates made to the fetchgroup definitions, using the fetchgroups tab are also made in the App.config file or in the source code as per your preference.

FetchGroup Attribute

The FetchGroup Attribute can be used to combine various FetchGroup definitions and is needed for performance fine-tuning.

For example, assume you have two named FetchGroups, FG_EmpName, which retrieves the firstName and lastName fields of an Employee class and another FG_EmpAddress, which retrieves the Address field of the Employee class. You can use the FetchGroup attribute to create a new FetchGroup, named FG_EmpName_and_Address using:

C# Copy Code
[FetchGroup(FG_EmpName_and_Address, FG_EmpName, FG_EmpAddress)]
VB .NET Copy Code
<FetchGroup(FG_EmpName_and_Address, FG_EmpName, FG_EmpAddress)>

The resulting FetchGroup named FG_EmpName_and_Address is a combination of the two FetchGroups, i.e., FG_EmpName and FG_EmpAddress.

FetchGroup Attribute Properties

The FetchGroup attribute has the following properties:

  • Groups - gets the collection of referenced FetchGroups. You can combine various FetchGroups to a new one by specifying their names, as shown in the above section.
  • Name - gets the name of the FetchGroup. All FetchGroups with the same name are used at the same time. A descriptive name, for example a use case name, makes it easier to see what exactly the FetchGroup is being used for. It is recommended to use symbolic constants for the names of the FetchGroups, this avoids hard to find problems occurring from misspelled strings and it also structures the usage of FetchGroups more cleanly.

FetchField Attribute

The FetchField attribute is used to mark fields to be included in the named FetchGroup. All the fields that are marked with this attribute will be loaded, along with the object, when it is initially retrieved from the database, as a result of a query or while resolving a reference. The [FetchField] attribute can be added to a field as shown below:

C# Copy Code
[Persistent] public abstract class Product { private int productNo; [FetchField("FG_ProductName")] private string name; }
VB .NET Copy Code
<Persistent> _
Public MustInherit Class Product
 Private productNo As Integer
 <FetchField("FG_ProductName")> _
 Private name As String
End Class

In the above example, you have a product class, with fields, productNo and name. The productNo has not been marked with the FetchField attribute, and therefore it is not part of the named FetchGroup, "FG_ProductName". Whereas, the name field has been marked with the FetchField attribute, and therefore it will be part of the named FetchGroup, "FG_ProductName". This means that, only the name field will be will be loaded, along with the object, when it is initially retrieved from the database, as a result of a query or while resolving a reference. Of course, this is only true when the default FetchGroup is not included in the actual FetchPlan definition, since int is a basic type.

The [FetchField] attribute requires that the containing class be marked as [Persistent]. The [FetchField] attribute can be used multiple times on the same field when this field needs to be included in multiple FetchGroups. You can accomplish the same effect by nesting the FetchGroup definitions with the [FetchGroup] attribute.

The XML entry (in the App.config file) for simple fields (name) corresponding to the above example will appear as below:

XML Copy Code
<class name="Product">
 
<fetch-group name="FG_ProductName">
   
<field name="name"/>
 
</fetch-group>
</
class>

In case of reference fields (customer), the following XML entry will be added to the App.config file:

XML Copy Code
<class name="Product">
 
<fetch-group name="FG_ProdNo_Cust">
   
<field name="productNo"/>
   
<field name="customer"/>
 
</fetch-group>
</
class>

Using the FetchField attribute the entry corresponding to the above example (for reference fields) will appear as below:

C# Copy Code
[Persistent]
public abstract class Product
{
   [FetchField(
"FG_ProdNo_Cust" )]
   
private int productNo;
   
private string name;
   [FetchField(
"FG_ProdNo_Cust" )]
   
private Customer customer;
}
VB .NET Copy Code
  <Persistent> _
  Public MustInherit Class Product
 <FetchField("FG_ProdNo_Cust")> _
 Private productNo As Integer
 Private name As String
 <FetchField("FG_ProdNo_Cust")> _
 Private customer As Customer
  End Class

In case of collection fields (details), the following XML entry will be added to the App.config file:

XML Copy Code
<class name="Product">
 
<fetch-group name="FG_ProdNo_Details">
   
<field name="productNo"/>
   
<field name="details"/>
 
</fetch-group>
</
class>

Using the FetchField attribute, the entry corresponding to the above example (for collection fields) will appear as below:

C# Copy Code
[Persistent]
public abstract class Product
{
   [FetchField(
"FG_ProdNo_Details" )]
   
private int productNo;
   
private string name;
   
private Customer customer;
   [FetchField(
"FG_ProdNo_Details" )]
   
private IList<OrderDetail> details;
}
VB .NET Copy Code
<Persistent> _
Public MustInherit Class Product
 <FetchField("FG_ProdNo_Details")> _
 Private productNo As Integer
 Private name As String
 Private customer As Customer
 <FetchField("FG_ProdNo_Details")> _
 Private details As IList(Of OrderDetail)
End Class

In case of maps (hashfield), the following XML entry will be added to the App.config file:

XML Copy Code
<class name="Product">
 
<fetch-group name="FG_ProdNo_Map">
   
<field name="productNo"/>
   
<field name="accounts#key" fetch-depth="1" />
   
<field name="accounts#value />"
 
</fetch-group>
</
class>

Using the FetchField attribute, the entry corresponding to the above example (for maps) will appear as below:

C# Copy Code
[Persistent]
public abstract class Product
{
   [FetchField(
"FG_ProdNo_Map" )]
   
private int productNo;
   
private string name;
   
private Customer customer;
   
private IList<OrderDetail> details;
   [FetchField(
"FG_ProdNo_Map", KeyDepth = 1 )]
   
private Hashtable accounts;
}
VB .NET Copy Code
<Persistent> _
Public MustInherit Class Product
 <FetchField("FG_ProdNo_Map")> _
 Private productNo As Integer
 Private name As String
 Private customer As Customer
 Private details As IList(Of OrderDetail)
 <FetchField("FG_ProdNo_Map", KeyDepth:=1)> _
 Private accounts As Hashtable
End Class

In case of maps it is not possible to have the Key without the Value. For example, the user cannot explicitly just specify the Key part of a map object with the FetchField attribute; this is possible if you are using XML entries. For example:

XML Copy Code
<class name="Product">
 
<fetch-group name="FG_Map_Key">
   
<field name="accounts#key" fetch-depth="1" />
 
</fetch-group>
</
class>

However it is possible to just have the Value part of a map object in both the attribute and XML form as shown below:

XML Copy Code
<class name="Product">
 
<fetch-group name="FG_Map_Value">
   
<field name="accounts#value />"
 
</fetch-group>
</
class>
C# Copy Code
[Persistent]
public abstract class Product
{
   [FetchField(
"FG_Map_Value" )]
   
private Hashtable accounts;
}
VB.NET Copy Code
<Persistent> _ Public MustInherit Class Product <FetchField("FG_Map_Value")> _ Private accounts As Hashtable End Class

FetchField Parameters

  • Depth - the Depth parameter helps in controlling the amount of data retrieved from the database, in cases where an object of a particular type refers to an object of the same type. That is, the Depth parameter defines the maximum depth the referenced objects are fetched from the root instances. For example, if you have Person with Children (that are also Person objects) an unlimited Depth will fetch all connected persons, therefore in such cases by default the Depth is set to "1".The Depth parameter can be added to a field as shown below:
    C# Copy Code
    [Persistent]
    public class Employee
    {
       [FetchField(
    "FG_EmpDetails", Depth = 2 )]
       
    private Department dept;
    }
    VB.NET Copy Code
    <Persistent> _
      Public Class Employee
     <FetchField("FG_EmpDetails", Depth:=2)> _
     Private dept As Department
    End Class
    The fetch-depth attribute defines the depth of references, in cases where an object of a particular type refers to an object of the same type. The XML entry corresponding to the above example is given below:
    XML Copy Code
    <class name="Employee">
     
    <fetch-group name="FG_EmpDetails">
       
    <field name="dept" fetch-depth="2"/>
     
    </fetch-group>
    </
    class>
    The following XML entry will be specified for the depth of references in case of the Key part of maps:
    XML Copy Code
    <class name="Product">
     
    <fetch-group name="FG_Map_Key">
       
    <field name="accounts#key" fetch-depth="2"/>
     
    </fetch-group>
    </
    class>
    In the source code, the Depth parameter for the Key part of a map object is named as KeyDepth. The corresponding entry in the source code for the above example will appear as below:
    C# Copy Code
    [Persistent]
    public abstract class Product
    {
       [FetchField(
    "FG_Map_Key", KeyDepth = 2 )]
       
    private Hashtable accounts;
    }
    VB.NET Copy Code
    <Persistent> _
      Public MustInherit Class Product
     <FetchField("FG_Map_Key", KeyDepth:=2)> _
     Private accounts As Hashtable
    End Class
    Similarly the following XML entry will be specified for the depth of references in case of the Value part of maps:
    XML Copy Code
    <class name="Product">
     
    <fetch-group name="FG_Map_Value">
       
    <field name="accounts#value" fetch-depth="2"/>
     
    </fetch-group>
    </
    class>
    In the source code, the Depth parameter for the Value part of a map object is the same as in case of the other fields, i.e., Depth. The corresponding entry in the source code for the above example will appear as below:
    C# Copy Code
    [Persistent]
    public abstract class Product
    {
       [FetchField(
    "FG_Map_Value", Depth = 2 )]
       
    private Hashtable accounts;
    }
    VB.NET Copy Code
    <Persistent> _
      Public MustInherit Class Product
     <FetchField("FG_Map_Value", Depth:=2)> _
     Private accounts As Hashtable
    End Class
    The depth of the fetching operation is also limited by the FetchPlan.MaxDepth property. It might be necessary to increase this value too to achieve the desired fetch effect. The Depth parameter is only used if the reference points to exactly the same type as the holding type (Person -> Person). In this case, by default the Depth is set to "1". This restriction is present for safety reasons for cases where the global depth (the FetchPlan.MaxDepth property) has been set to infinite and circular references could retrieve the complete database. This restriction is not in place if the circular references are indirect (Person -> Company -> Person).
  • Name - contains the name of the FetchGroup.
  • Next - the Next parameter sets a FetchGroup at the referenced class as the FetchGroup to be used. If it is necessary to fetch a referenced object with a specific FetchGroup definition you can specify it using the Next parameter. The Next FetchGroup is added only to the FetchPlan definition if the object is retrieved via this reference. The FetchGroup name must be part of the actual FetchPlan. The Next parameter can be added to a field as shown below:
    C# Copy Code
    [Persistent]
    public class Person
    {
       
    private string firstName;
       [FetchField(
    "FG_Person_Add", Next = "FG_Add_CityMap" )]
       
    private Address address;
    }

    [Persistent]
    public class Address
    {
       [FetchField(
    "FG_Add_CityMap" )]
       
    private Blob cityMap;
    }
    VB.NET Copy Code
    <Persistent> _
      Public Class Person
     Private firstName As String
     <FetchField("FG_Person_Add", Next:="FG_Add_CityMap")> _
     Private address As Address
    End Class

    <Persistent> _
    Public Class Address
     <FetchField("FG_Add_CityMap")> _
     Private cityMap As Blob
    End Class
    In the example above, we have a person class, with an address field, which has been marked with the [FetchField] attribute along with the Next parameter. Also, we have an Address class, which has the cityMap field marked with the [FetchField] attribute. This means that, when the person object is retrieved, both the address field and the cityMap field will be retrieved. The XML entry corresponding to the above example is given below:
    XML Copy Code
    <class name="Person">
     
    <fetch-group name="FG_Person_Add">
       
    <field name="address" fetch-group="FG_Add_CityMap"/>
     
    </fetch-group>
    </
    class>
    <
    class name="Address">
     
    <fetch-group name="FG_Add_CityMap">
       
    <field name="cityMap"/>
     
    </fetch-group>
    </
    class>
    The following XML entry is used for specifying the next fetchgroup to be used while retrieving the keys of a map object:
    XML Copy Code
    <class name="Product">
     
    <fetch-group name="FG_Map_Key">
       
    <field name="accounts#key" fetch-group="FG_order_map"/>
     
    </fetch-group>
    </
    class>
    In the source code, the Next parameter, for the Key part of a map object is named as KeyNext. The corresponding entry in the source code for the above example will appear as below:
    C# Copy Code
    [Persistent]
    public abstract class Product
    {
       [FetchField(
    "FG_Map_Key", KeyNext = "FG_order_map" )]
       
    private Hashtable accounts;
    }
    VB.NET Copy Code
    <Persistent> _
      Public MustInherit Class Product
     <FetchField("FG_Map_Key", KeyNext:="FG_order_map")> _
     Private accounts As Hashtable
    End Class
    Similarly the following XML entry is used for specifying the next fetchgroup to be used while retrieving the values of a map object:
    XML Copy Code
    <class name="Product">
       
    <fetch-group name="FG_Map_Value">
           
    <field name="accounts#value" fetch-group="FG_order_map"/>
       
    </fetch-group>
    </
    class>
    In the source code, the Next parameter, for the Value part of a map object is the same as in case of the other fields, i.e., Next. The corresponding entry in the source code for the above example will appear as below:
    C# Copy Code
    [Persistent]
    public abstract class Product
    {
       [FetchField(
    "FG_Map_Value", Next = "FG_order_map" )]
       
    private Hashtable accounts;
    }
    VB.NET Copy Code
    <Persistent> _
      Public MustInherit Class Product
     <FetchField("FG_Map_Value", Next:="FG_order_map")> _
     Private accounts As Hashtable
    End Class
  • Path - If you need a specific field at the referenced object it is not necessary to define a FetchGroup at the referenced class. You can use the Path argument to do this indirectly. The "Path" parameter specifies an additional path to follow, in case of referenced classes. The Path parameter can be added to a field as shown below:
    C# Copy Code
    [Persistent]
    public class Person
    {
       
    private string firstName;
       [FetchField(
    "FG_Person_Add", Path = "cityMap" )]
       
    private Address address;
    }
    VB.NET Copy Code
    <Persistent> _
      Public Class Person
     Private firstName As String
     <FetchField("FG_Person_Add", Path:="cityMap")> _
     Private address As Address
    End Class
    In the example above, the [FetchField] attribute, along with the "Path" parameter, has been added to a referenced class, i.e. to the address class. Therefore, in this case, the additional path to follow is the "cityMap" field of the address class, i.e., only the "cityMap" field of the address class (and not all the fields of the address class) will be retrieved from the database initially, as a result of a query or while resolving a reference. The Path is set using the "." operator. The XML entry corresponding to the above example is given below:
    XML Copy Code
    <class name="Peron">
       
    <fetch-group name="FG_Person_Add">
           
    <field name="address.cityMap"/>
       
    </fetch-group>
    </
    class>
    Using the "Path" parameter provides you with a shortcut. You can do the same, with the help of the "Next" parameter (described above):
    C# Copy Code
    [FetchField("FG_Person_Add", Next="FG_Add_CityMap")]
    private Address address;
    VB.NET Copy Code
    <FetchField("FG_Person_Add", Next:="FG_Add_CityMap")> _
    Private address As Address
    Then you will need to specify the referenced fields directly at field level (using the [FetchField] attribute) in the referenced class.

    Only one of the above methods can be used in a single [FetchField] definition.

    You also can traverse more than one level using the "." separator. If the field is a collection the Path can be specified using #element.childname. If the field is a dictionary then the Path will be specified as #key.fieldname (for the Key part of the map object) and #value.fieldname (for the Value part of the map object). The following XML entry is used for specifying the path to be used while retrieving the keys of a map object:
    XML Copy Code
    <class name="Product">
       
    <fetch-group name="FG_Map_Key">
           
    <field name="accounts#key.name"/>
       
    </fetch-group>
    </
    class>
    In the source code, the Path parameter for the Key part of a map object is named as KeyPath. The corresponding entry in the source code for the above example will appear as below:
    C# Copy Code
    [Persistent]
    public abstract class Product
    {
       [FetchField(
    "FG_Map_Key", KeyPath = "name" )]
       
    private Hashtable accounts;
    }
    VB.NET Copy Code
    <Persistent> _
      Public MustInherit Class Product
     <FetchField("FG_Map_Key", KeyPath:="name")> _
     Private accounts As Hashtable
    End Class
    Similarly the following XML entry is used for specifying the path to be used while retrieving the values of a map object:
    XML Copy Code
    <class name="Product">
       
    <fetch-group name="FG_Map_Value">
           
    <field name="accounts#value.code"/>
       
    </fetch-group>
    </
    class>
    In the source code, the Path parameter for the Value part of a map object is the same as in case of the other fields, i.e., Path. The corresponding entry in the source code for the above example will appear as below:
    C# Copy Code
    [Persistent]
    public abstract class Product
    {
       [FetchField(
    "FG_Map_Value", Path = "code" )]
       
    private Hashtable accounts;
    }
    VB.NET Copy Code
    <Persistent> _
      Public MustInherit Class Product
     <FetchField("FG_Map_Value", Path:="code")> _
     Private accounts As Hashtable
    End Class

    It is possible to specify either the Next FetchGroup to be used or the Path to be followed and not both.

See Also