Blue Theme Orange Theme Green Theme Red Theme
 
MindFusion's Components
Home | Forums | Videos | Photos | Blogs | E-Books | Interviews | Jobs | Beginners | Training
 | Consulting  
Submit an Article 
 Login Close
User Id:
Password:
 
Forgot Password
Forgot Username
Why Register
 Jump to
Skip Navigation Links
TechnologyExpand Technology
WebsiteExpand Website
 Resources  
Close
 Our Network  
Close
Search :       Advanced Search »
Home » LINQ » Cascading Deletes in LINQ to SQL

Cascading Deletes in LINQ to SQL

This article will discuss alternative methods for performing cascading deletes using LINQ to SQL. Cascading delete refers to the action of removing records associated by a foreign key relationship to a record that is the target of a deletion action.

Author Rank:
Technologies: .NET Compact Framework, .NET Compact Framework,Visual C# .NET
Total downloads :
Total page views :  3112
Rating :
 5/5
This article has been rated :  1 times
   Print Read/Post comments Post a comment  Rate  
   Email to a friend  Bookmark  Similar Articles  Author's other articles  
 
ArticleAd
Become a Sponsor



Introduction

This article will discuss alternative methods for performing cascading deletes using LINQ to SQL.  Cascading delete refers to the action of removing records associated by a foreign key relationship to a record that is the target of a deletion action.  LINQ to SQL does not specifically handle cascading deletes and it is up to the developer to determine whether or not that action is desired.  It is also up to the developer to determine how to go about accomplishing the cascading delete.

Problem

The problem with performing a cascading delete is not new to LINQ to SQL and one has essentially the the same alternatives for performing such a delete.  The issue is one of determining how to handle the deletion or retention of records associated with a record targeted for deletion where that record maintains a foreign key relationship with records contained within other tables within the database and more specifically where the foreign key fields are not nullable.

As an example, consider the customer table within the Northwind database.  The customer table has a foreign key relationship established with the Orders table (which in turn maintains a foreign key relationship with the Order_Details table).  In order to delete a customer which has associated Orders, one needs to dispose of or otherwise handle the associated records in both the Orders and Order_Details tables.  In the LINQ to SQL jargon, the associated tables are referred to as entity sets.

LINQ to SQL will not violate the foreign key relationships and if an application attempts to delete a record with such relationships in place, the executing code will throw an exception.  Using the Northwind example, if one were to attempt to delete a customer with associated orders, an exception will occur.  That is not really a problem, that is how it should be, otherwise, why have foreign key relationships at all.  The issue is really one of determining if you would really want to delete records with associated entity sets, and if you do, how would you want to handle it - do you want to keep the associated records or delete them right along with the targeted record?

Figure 1:  Customers, Orders, and Order Details - Northwind Database

Solution

There are several possible alternatives at your disposal.  You can handle the cascading deletes using LINQ to SQL from within your code, or you can handle the foreign key relationships from within SQL Server.

If you were to execute this code against the Northwind database, it would create a customer with an associated order and order details.

try

{

          Customer c = new Customer();

          c.CustomerID = "AAAAA";

          c.Address = "554 Westwind Avenue";

          c.City = "Wichita";

          c.CompanyName = "Holy Toledo";

          c.ContactName = "Frederick Flintstone";

          c.ContactTitle = "Boss";

          c.Country = "USA";

          c.Fax = "316-335-5933";

          c.Phone = "316-225-4934";

          c.PostalCode = "67214";

          c.Region = "EA";

 

          Order_Detail od = new Order_Detail();

          od.Discount = .25f;

          od.ProductID = 1;

          od.Quantity = 25;

          od.UnitPrice = 25.00M;

 

          Order o = new Order();

          o.Order_Details.Add(od);

          o.Freight = 25.50M;

          o.EmployeeID = 1;

          o.CustomerID = "AAAAA";

 

          c.Orders.Add(o);

 

          using (NWindDataContext dc = new NWindDataContext())

          {

                   var table = dc.GetTable<Customer>();

                   table.InsertOnSubmit(c);

                   dc.SubmitChanges();

          }

}

catch (Exception ex)

{

          MessageBox.Show(ex.Message);

}

But if you then tried to delete the customer without handling the entity sets using something like this:

using (NWindDataContext dc = new NWindDataContext())

{

 

          var q =

                   (from c in dc.GetTable<Customer>()

                   where c.CustomerID == "AAAAA"

                   select c).Single<Customer>();

 

                   dc.GetTable<Customer>().DeleteOnSubmit(q);

                   dc.SubmitChanges();

}

It would result an error and no changes would be made to the database:

Figure 2:  Conflict Error Message

Solution Alternative 1 - Handling the Delete with LINQ to SQL

You can handle the cascading deletes manually deleting all of the related entities in the associated entity set; here is a simple approach to doing that:

try

{

          using (NWindDataContext dc = new NWindDataContext())

          {

 

                   var q =

                   (from c in dc.GetTable<Customer>()

                   where c.CustomerID == "AAAAA"

                   select c).Single<Customer>();

 

                   foreach (Order ord in q.Orders)

                   {

                             dc.GetTable<Order>().DeleteOnSubmit(ord);

 

                             foreach (Order_Detail od in ord.Order_Details)

                             {

                                       dc.GetTable<Order_Detail>().DeleteOnSubmit(od);

                             }

                    }

                    dc.GetTable<Customer>().DeleteOnSubmit(q);

                    dc.SubmitChanges();

          }

          UpdateDataGrid();

}

catch (Exception ex)

{

          MessageBox.Show(ex.Message);

}

In looking at this example, to delete the customer along with the related orders and order details, the code first selects the matching customer by the customer ID field (it's primary key).  Once a match is found, the code loops through the orders related to each customer and marks them for deletion using the DeleteOnSubmit call. 

Further, since another relationship exists between the order and order details, the code loops through all of the order details associated with the order and marks them for deletion as well.  Lastly, the customer itself if marked for deletion and then Submit Changes is called on the data context.  The order in which the entities are marked for deletion does not matter, LINQ to SQL sorts that out during the execution of the Submit Changes call based upon the configuration of the foreign keys.

Solution Alternative 2 - Handling the Cascading Delete from within SQL Server

It is possible to manage the cascading deletes entirely from within SQL Server.  To do this, one need only set the delete rule for the foreign key relationship to cascade.

Figure 3.  Setting the Delete Rule

If you have a database diagram built, the easiest way to set the delete rule is to merely open the diagram, click on the foreign key relationship within the diagram, and then open the INSERT and UPDATE property to expose the Delete Rule property, and then set the Delete Rule property to Cascade as shown in Figure 3.

To repeat the example of deleting a customer with related orders, if we were to set all of the constraint delete rules to cascade we could delete a customer with this bit of code:

try

{

          using (NWindDataContext dc = new NWindDataContext())

          {

                   var q =

                   (from c in dc.GetTable<Customer>()

                   where c.CustomerID == "AAAAA"

                   select c).Single<Customer>();

 

                   dc.GetTable<Customer>().DeleteOnSubmit(q);

                   dc.SubmitChanges();

          }

          UpdateDataGrid();

}

catch (Exception ex)

{

          MessageBox.Show(ex.Message);

}

As you can see in this example code, there was not need to bother with marking each member of an entity set for deletion as in this case SQL Server was instructed on how to deal with a deletion of the customer or order records.  As a result, deleting the customer also results in the deletion of the relation records contained in the Order and Order Details tables.
 
Solution Alternative 3 - Handling the Cascading Delete From within SQL Server

It is also possible to set the foreign key field in the entity sets to nullable and then set the delete rule for that field to "Set Null".  One could also set a default value for the field and set the delete rule to "Set Default".  Either approach could be useful if there was a need to delete (in this example) a customer record but retain the order and order detail records.  Either approach could be handled in a manner similar to that used in the previous solution alternative.  Setting the foreign key value to nullable is probably not advisable but it is a workable alternative.

Solution Alternative 4 - Handling the Cascading Delete With a Stored Procedure

One may create or add a stored procedure that will accomplish the cascading delete and evoke that stored procedure using LINQ to SQL.  Stored procudures added to the designer may be evoked directly from the data context, for example, if we had stored procedure called DeleteCustomer that took the customer ID as an argument and handled the cascading deletes, we could do something like this:

Using(NwindDataContext dc = new NwindDataContext())
{
     dc.DeleteCustomer("AAAAA");
}

Summary

Cascading deletes are not new to LINQ to SQL; it is the same issue it has always been.  In this article I have described a few approaches to dealing with cascading deletes from within the code and from the SQL Server side but as is true with many things in .NET, there are several other ways to accomplish such an action from within LINQ to SQL.


Login to add your contents and source code to this article
 [Top] Rate this article
 About the author
 
Scott Lysle
Freelance software developer residing in Alabama. Bachelors, Masters Degrees from Wichita State University. I spent the first half of my career working on aircraft controls and displays and in that time I worked on the cockpits for the OH-58 AHIP, the AH-1W, the V-22, the F-22, the C-130J, the C-5 AMP, AWACS, JPATS, and a few others. Since 1997 I have been largely involved with Windows and web development, GIS application development, consumer electronics development (embedded linux/java), but still sometimes work on aircraft and military projects, the most recent of which was the presidential transport helicopter. I tend to work primarily with C/C++, Java, VB, and C#.
Looking for C# Consulting?
C# Consulting is founded in 2002 by the founders of C# Corner. Unlike a traditional consulting company, our consultants are well-known experts in .NET and many of them are MVPs, authors, and trainers. We specialize in Microsoft .NET development and utilize Agile Development and Extreme Programming practices to provide fast pace quick turnaround results. Our software development model is a mix of Agile Development, traditional SDLC, and Waterfall models.
Click here to learn more about C# Consulting.
 
Introducing MaxV - one click. infinite control. Hyper-V Hosting from MaximumASP.
Finally – a virtual platform that delivers next-generation Windows Server 2008 Hyper-V virtualization technology from a managed hosting partner you can truly depend on. Visit www.maximumasp.com/max for a FREE 30 day trial. Hurry offer ends soon. Climb aboard the MaxV platform and take advantage of High Availability, Intelligent Monitoring, Recurrent Backups, and Scalability – with no hassle or hidden fees. As a managed hosting partner focused solely on Microsoft technologies since 2000, MaximumASP is uniquely qualified to provide the superior support that our business is built on. Unparalleled expertise with Microsoft technologies lead to working directly with Microsoft as first to offer IIS 7 and SQL 2008 betas in a hosted environment; partnering in the Go Live Program for Hyper-V; and product co-launches built on WS 2008 with Hyper-V technology.
Dynamic PDF
ceTE software specializes in components for dynamic PDF generation and manipulation. The DynamicPDF™ product line allows you to dynamically generate PDF documents, merge PDF documents and new content to existing PDF documents from within your applications.
Boost the performance of your .NET applications
“ANTS Profiler took us straight to the specific areas of our code which were the cause of our performance issues." Terry Phillips, Sr. Developer, Harley-Davidson Dealer Systems. Download your free trial of ANTS Profiler.
Go.NET
Build custom interactive diagrams, network, workflow editors, flowcharts, or software design tools. Includes many predefined kinds of nodes, links, and basic shapes. Supports layers, scrolling, zooming, selection, drag-and-drop, clipboard, in-place editing, tooltips, grids, printing, overview window, palette. 100% implemented in C# as a managed .NET Control. Document/View/Tool architecture with many properties&events. Optional automatic layout.
Dundas Software
Dundas Chart for .NET is the most advanced .NET charting package available today.  With an extremely complete feature set, elegant architecture and easy implementation, Dundas Chart can quickly add advanced Charting functionality to enhance and transform ASP.NET and Windows Forms applications.  Whether you are implementing charting into internal projects, or building applications for clients, Dundas Chart offers advanced technology and advanced results to get the most out of data.
 
   Print Read/Post comments Post a comment  Rate  
   Email to a friend  Bookmark  Similar Articles  Author's other articles  
 
 Post a Feedback, Comment, or Question about this article
Subject:  
Comment:  
ArticleAd
Become a Sponsor
Latest Comments:
Subject Posted By Posted On

 Hosted by MaximumASP  |  Found a broken link?  |  Contact Us  |  Terms & conditions  |  Privacy Policy  |  Site Map  |  Suggest an Idea  |  Media Kit
Current Version: 5.2009.6.2
 © 1999 - 2009  Mindcracker LLC. All Rights Reserved