Possible Duplicate:
Delete object and all its child objects in Entity Framework?
This code:
int WebsiteID = int.Parse(Request.QueryString["id"]);
Website websiteObj = db.Websites
.SingleOrDefault(x => x.website_id == WebsiteID);
foreach (BusinessObjects.Page pageObj in websiteObj.Pages)
{
foreach (SubPage subpageObj in pageObj.SubPages)
{
pageObj.SubPages.Remove(subpageObj);
}
websiteObj.Pages.Remove(pageObj);
}
foreach (Sector sectorObj in websiteObj.Sectors)
{
foreach (Product productObj in sectorObj.Products)
{
sectorObj.Products.Remove(productObj);
}
websiteObj.Sectors.Remove(sectorObj);
}
db.Websites.DeleteObject(websiteObj);
A website has multiple pages, a page has multiple subpages. A website also has multiple sectors and each sector has multiple products.
I want to delete the website and clear all relationships + entities related to it. I’m sure there are better ways to write the above.
Is there way to improve the logic?
The simplest way, is to set up the relationships in the database as
ON DELETE CASCADEThen the Linq becomes:
The only real changes I’ve made to your linq apart from removing what is no longer needed if deletes cascade is:
Using
FirstOrDefaultfor a slight performance boost. This isn’t too big a deal with databases, as it just does aTOP 2to implement. It’s worth not doingSinglewhenFirstworks, because in other cases it can mean having to examine every single object (only way to doSingleagainst aList<T>)*. Of course, if there’s any possibility of there being two sites with the same id, then I’ve just introduced a bug, but then the real bug is in not having the id as a primary key to ensure that this could never happen.Taking
Objout of the name of the object. This seemed to be short for “object” and hence to be tautologous – every other variable in every piece of .NET code ever written is for an object, so there’s no point in pointing this out.*A bit more on this because I don’t want to encourage bad habits. When there can be only one matching object, then
Firstgets that object whileSinglegets that object and also makes sure it is the only one (the same applies to theOrDefaultvariants except they differ when there is no object found at all).The only way to know there’s only one matching object, is to try to find at least two of them and then check you only got one. This is of minor impact with a database table if it’s indexed on columns relevant to your search (it does a
TOP 2instead of aTOP 1), but can be serious otherwise.The question is how important that is for that check to be made. Sometimes you don’t care; use
First. Sometimes you should have a strong degree of confidence that there is only one such object; useFirstbut do check on the reason for that confidence to make sure you don’t have a bug (in this case, check there’s a primary or unique key on the index column). If you really need to check then do useSingleas usingFirstin such a case is the very epitome of a bad optimisation – being faster but wrong is never the goal.