Data Access has been discontinued. Please refer to this page for more information.

Additional Association Configuration

This article is relevant to entity models that utilize the deprecated Visual Studio integration of Telerik Data Access. The current documentation of the Data Access framework is available here.

This topic will show you how to configure additional association properties, such as DataAccessKind, LoadBehavior, how to create transient associations and generate foreign key constraints in the database:

Creating Managed Associations

The Product and Category entities are connected through the one-to-many association. The Product entity has one instance of Category. You can use the product.Category property to access the Category instance that is associated with an instance of the Product entity. The Category entity has many instances of Product. You can use the category.Products property to access the Product instances that are associated with an instance of the Category entity.

Suppose, you want to insert new product and category objects in the database, and you want to set a new relation between the objects. The most simple way to do this is to use the product.Category property.

product.Category = newCategory;
product.Category = newCategory

There is another approach you can use to specify the relation between the Product and Category objects. Instead of using the newProduct.Category property, you can use the newCategory.Products collection property.

newCategory.Products.Add(newProduct);
newCategory.Products.Add(newProduct)

However, there is one important condition here. You need to specify the product.Categories association as managed. The following example demonstrates how to create managed associations.

categoryConfiguration.HasAssociation(c => c.Products).WithOpposite(p => p.Category).
    HasConstraint((c, p) => c.Id == p.CategoryId).IsManaged();
categoryConfiguration.HasAssociation(Of Product)(Function(c) c.Products). _
    WithOpposite(Function(p) p.Category).HasConstraint(Function(c, p) c.Id = p.CategoryId). _
    IsManaged()

Creating Dependent Associations

When you want to automatically delete all of the child records of a parent record when the parent record is deleted, you need to perform a cascading delete. Usually, the referenced table is called the parent table while the table with the foreign key is called the child table.

For example, when you delete a category you want to delete all related products as well. Cascading deletes are disabled by default and are only enabled for references specified as dependent.

The following example demonstrates how to create dependant associations.

categoryConfiguration.HasAssociation(c => c.Products).WithOpposite(p => p.Category).
    HasConstraint((c, p) => c.Id == p.CategoryId).IsDependant();
categoryConfiguration.HasAssociation(Of Product)(Function(c) c.Products). _
    WithOpposite(Function(p) p.Category).HasConstraint(Function(c, p) c.Id = p.CategoryId). _
    IsDependant()

Using the ToColumn Method

Another way to define an association is to use the ToColumn method. The ToColumn method specifies the column name that this navigation property is mapped to. Or in other words, the ToColumn method specifies the foreign key column. Note that the ToColumn method will add the foreign key column to the appropriate table even if it is defined on the type that has the collection end.

productConfiguration.HasAssociation(p => p.Category).WithOpposite(c => c.Products).
    ToColumn("CategoryId");
productConfiguration.HasAssociation(Function(p) p.Category). _
    WithOpposite(Function(c) c.Products).ToColumn("CategoryId")

Creating Transient Associations

The Fluent Mapping API gives you an option to configure a given association as transient. Thus, this association will not be included in the metadata model and will not be taken into account by Telerik Data Access at runtime.

productConfiguration.HasAssociation(p => p.Category).WithOpposite(c => c.Products).
    AsTransient();
productConfiguration.HasAssociation(p => p.Category).WithOpposite(c => c.Products). _
    AsTransient()

For example, the following code will insert new category and product objects in the database. However, the product.CategoryId column will be set to null because the corresponding association is declared as transient.

using (FluentModelContext fluentModelContext = new FluentModelContext())
{
   Category category = new Category();
   category.Id = 1;
   category.Name = "Test";

   Product product = new Product();
   product.Category = category;

   fluentModelContext.Add(product);
   fluentModelContext.Add(category);
   fluentModelContext.SaveChanges();
}
Using _fluentModelContext As New FluentModelContext()
 Dim _category As New Category()
 _category.Id = 1
 _category.Name = "Test"

 Dim _product As New Product()
 _product.Category = _category

 _fluentModelContext.Add(_product)
 _fluentModelContext.Add(_category)
 _fluentModelContext.SaveChanges()
End Using

Setting DataAccessKind

You could specify the DataAccessKind for the association by using the WithDataAccessKind method. The DataAccessKind specifies the type of access for the entity. It could be:

  • Default - specifies that the default value for the data access kind (read/write) will be used by the runtime.
  • ReadWrite - the type allows full access to the data. All CRUD modifications are allowed.
  • InsertOnly - the type allows only reading and inserting operations. No modifications (update or delete) are allowed.
  • ReadOnly - the type is read-only. No CUD modifications (create, update or delete) are allowed.
productConfiguration.HasAssociation(p => p.Category).
    WithDataAccessKind(Telerik.OpenAccess.DataAccessKind.ReadOnly).
    WithOpposite(c => c.Products);
productConfiguration.HasAssociation(Function(p) p.Category). _
    WithDataAccessKind(Telerik.OpenAccess.DataAccessKind.ReadOnly). _
    WithOpposite(Function(c) c.Products)

Setting LoadBehavior

You could specify the LoadBehavior for the association by using the WithLoadBehavior method. It could be:

  • Default - the default behavior. The runtime will decide whether to load it or not based on the type of the property.
  • Lazy - the property marked with this facet will be lazily loaded.
  • Eager - the property marked with this facet will be eagerly loaded.
productConfiguration.HasAssociation(x => x.Category).
    WithLoadBehavior(Telerik.OpenAccess.LoadBehavior.Lazy).
    WithOpposite(c => c.Products);
productConfiguration.HasAssociation(Function(x) x.Category). _
    WithLoadBehavior(Telerik.OpenAccess.LoadBehavior.Lazy). _
    WithOpposite(Function(c) c.Products)