How to: Delete Objects
In order to delete an object from the database the following steps should be performed:
- You need a reference to the target object.
- Pass the object to the OpenAccessContext's Delete method.
- Invoke the SaveChanges method.
For example:
Customer customerToDelete = dbContext.Customers.Last();
dbContext.Delete( customerToDelete );
dbContext.SaveChanges();
Dim customerToDelete As Customer = dbContext.Customers.Last()
dbContext.Delete(customerToDelete)
dbContext.SaveChanges()
To remove an existing relation between objects in one-to-many relationship, simply use the object.Collection.Remove method. For example: category.Cars.Remove(car). To get this code working you need to change the mapping configuration of the Category.Cars property to include a call to the IsManaged method. For more information, read How to: Manage One-to-Many Association.
How to: Perform Cascading Delete
This section demonstrates how to automatically delete objects which are in parent-child relations using Telerik Data Access. 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.
Suppose, you have the following two tables in the database:
The Products table has a reference to the Categories table. Usually, the referenced table is called the parent table while the table with the foreign key is called the child table. In this example the Products table is the child table, and the Categories table is the parent table. A foreign key with a cascade delete means that if a record in the parent table is deleted, then the corresponding records in the child table will be deleted automatically. This is called a cascade delete.
Configuring Your model to Support Cascading Delete
Suppose, you have created a model reflecting the Categories and Products tables.
Cascading deletes are disabled by default and are only enabled for references specified as dependent. In order to configure your model to support cascading delete, you need to perform few simple steps:
- Go through the mapping configuration of the model and locate configuration relevant to the parent entity - in this example, this is the Category entity.
-
In the mapping configuration of the Category.Products, add a call to the IsDependent method.
categoryConfiguration.HasAssociation(x => x.Products). HasFieldName("_products").WithOpposite(x => x.Category). ToColumn("CategoryID").HasConstraint((y, x) => x.CategoryID == y.CategoryID ). IsDependent().WithDataAccessKind(DataAccessKind.ReadWrite);
categoryConfiguration.HasAssociation(x => x.Products). HasFieldName("_products").WithOpposite(x => x.Category). ToColumn("CategoryID").HasConstraint((y, x) => x.CategoryID == y.CategoryID ). IsDependent().WithDataAccessKind(DataAccessKind.ReadWrite)
In this example the Products property is specified as dependent. When you delete a specific Category object, then all referenced Product objects are deleted, too.
Telerik Data Access does not check for other references to the deleted dependent instances. If there are other references to the deleted dependent instances, you will get an exception. For example, consider the following model.
Consider the Northwind sample database and a fluent model based on it. The Products property of the Category class is configured as dependent. At the same time, the OrderDetails property of the Product entity is not configured as dependent. If you delete a specific Category object, Telerik Data Access will try to delete all related Products. However, if there are OrderDetail objects referencing any of the deleted dependent products, you will get an exception. The correct configuration here is to specify the Product.OrderDetails property as dependent as well.
productConfiguration.HasAssociation(x => x.OrderDetails).
HasFieldName("_orderDetails").WithOpposite(x => x.Product).
ToColumn("ProductID").HasConstraint((y, x) => x.ProductID == y.ProductID ).
IsDependent().WithDataAccessKind(DataAccessKind.ReadWrite);
productConfiguration.HasAssociation(x => x.OrderDetails).HasFieldName("_orderDetails").WithOpposite(x => x.Product).ToColumn("ProductID").HasConstraint((y, x) => x.ProductID == y.ProductID ).IsDependent().WithDataAccessKind(DataAccessKind.ReadWrite)
Thus, when you delete a Category object, Telerik Data Access will delete all related Product objects, and all OrderDetail objects related to the deleted Product.
One additional thing you should know about is that the cascade delete does not work in the "parent->child" direction only. You could configure your model so that the cascade delete is available in the opposite direction, too. For example, if you make the Category property of the Product entity dependent, then you will achieve the following result: when you delete a child entity (e.g. Product), the corresponding parent entity (e.g. Category) will be deleted too.