Skip to content

Codepolice

  • ⤫

Cascade delete in Entity Framework

Posted by Judy Alvarez Posted on February 25, 2022March 3, 2022
0

I had a really hard time getting a simple cascade delete to work with the Entity Framework and I thought I had to write it down here so that I can remember it in the future.

I was trying to delete an item from my database with some children. But I got the error

A relationship is being added or deleted from an AssociationSet ‘FK_ItemChildren_Item’. With cardinality constraints, a corresponding ‘ItemChildren’ must also be added or deleted.

I started to google on it and I found this thread in the MSDN forums. The first suggestion where to add cascade delete to the database and then update the model to get the changes. I did that but I still got the same error. The problem where this.

The SSDL part of the edmx file were updated correctly.

<Association Name="FK_ItemChildren_Item">
 <End Role="Item" Type="Model.Store.Item" Multiplicity="1">
  <OnDelete Action="Cascade" />
 </End>
 <End Role="ItemChildren" Type="Model.Store.ItemChildren"
  Multiplicity="*" />
 <ReferentialConstraint>
 ..
 </ReferentialConstraint>
</Association>

But the CSDL part where not updated:

<Association Name="FK_ItemChildren_Item">
 <End Type="Model.Item" Role="Item" Multiplicity="1">
  <OnDelete Action="Cascade"></OnDelete>
 </End>
 <End Type="Model.ItemChildren" Role="ItemChildren"
  Multiplicity="*">
 </End>
</Association>

The line in “<OnDelete Action=”Cascade”></OnDelete>” was not updated for some reason. When I added that in the model it worked. I guess the designer is not 100% even though the released EF.

UPDATE!

Alexander Muylaert sent me this script via the comments.

Thanks for your blog.  I had this issue on a huge model.  Over 180 tables and hundreds of references.  I didn’t feel like checking all this manually.

I open the edmx file as an xmldocument and executed the following code.  It fixes this issue in batch…  The code is not cleaned, but I have already lost a complete day and I can’t afford to waste more time.  I would like to post this, so someone could use this code and post a cleaned version.

private static string MakeKey(string aAssociation, string aRole) {
        return aAssociation + "_/_" + aRole;
    }

    public static void FixCascadeDeleteIssues(XmlDocument XDOC, XmlNode SSDLNode, XmlNode CSDLNode, ref bool aChanged) {
        HashSet lst = new HashSet();

        foreach (XmlNode SSDLChild in SSDLNode) {
            if (SSDLChild.Name == "Association") {
                foreach (XmlNode EndChild in SSDLChild) {
                    if (EndChild.Name == "End") {
                        foreach (XmlNode DeleteChild in EndChild) {
                            if (DeleteChild.Name == "OnDelete") {
                                var x = DeleteChild.Attributes.GetNamedItem("Action");
                                if (x.Value == "Cascade") {
                                    lst.Add(MakeKey(SSDLChild.Attributes.GetNamedItem("Name").Value, EndChild.Attributes.GetNamedItem("Role").Value));
                                }
                            }
                        }
                    }
                }
            }
        }

        Dictionary FMaps = new Dictionary();

        foreach (XmlNode CSDLChild in CSDLNode) {
            if (CSDLChild.Name == "EntityContainer") {
                foreach (XmlNode ContainerChild in CSDLChild) {
                    if (ContainerChild.Name == "AssociationSet") {
                        foreach (XmlNode EndChild in ContainerChild) {
                            if (EndChild.Name == "End") {
                                string Association = ContainerChild.Attributes.GetNamedItem("Name").Value;
                                string Role = EndChild.Attributes.GetNamedItem("Role").Value;
                                string EntitySet = EndChild.Attributes.GetNamedItem("EntitySet").Value;

                                FMaps.Add(MakeKey(Association, Role), EntitySet);
                            }
                        }
                    }
                }
            }
        }

        foreach (XmlNode CSDLChild in CSDLNode) {
            if (CSDLChild.Name == "Association") {
                string Association = CSDLChild.Attributes.GetNamedItem("Name").Value;

                if (Association == "FK_DEV_PARENT_DEV_ID") {
                    Console.WriteLine("");
                }

                foreach (XmlNode EndChild in CSDLChild) {
                    if (EndChild.Name == "End") {

                        string Multiplicity = EndChild.Attributes.GetNamedItem("Multiplicity").Value;
                        if (Multiplicity == "*") {
                            continue;
                        }

                        string role = EndChild.Attributes.GetNamedItem("Role").Value;
                        string v;
                        if (FMaps.TryGetValue(MakeKey(Association, role), out v)) role = v;
                        string key = MakeKey(CSDLChild.Attributes.GetNamedItem("Name").Value, role);

                        if (lst.Contains(key)) {
                            bool hasdel = false;
                            foreach (XmlNode DeleteChild in EndChild) {
                                if (DeleteChild.Name == "OnDelete") {
                                    var x = DeleteChild.Attributes.GetNamedItem("Action");
                                    if (x.Value == "Cascade") {
                                        hasdel = true;
                                    }
                                }
                            }
                            if (!hasdel) {
                                XmlNode newSub = XDOC.CreateNode(XmlNodeType.Element, "OnDelete", NamespaceDelete);
                                XmlAttribute xa = XDOC.CreateAttribute("Action", null);
                                xa.Value = "Cascade";
                                newSub.Attributes.Append(xa);
                                EndChild.AppendChild(newSub);
                                aChanged = true;
                            }
                        }
                    }
                }
            }
        }
    }
Categories: JavascriptTagged: .net core 5 mvc, .net mvc core, asp net and mvc difference, asp net core mvc login and registration using identity, asp net core mvc vs asp net mvc, asp net mvc 4 tutorial, asp net mvc application, asp net mvc certification, asp net mvc chart, asp net mvc codeproject, asp net mvc convert html to pdf, asp net mvc course, asp net mvc dersleri, asp net mvc ecommerce open source, asp net mvc electronic signature, asp net mvc generate pdf, asp net mvc jobs, asp net mvc print pdf, asp net mvc templates, c# asp net mvc, html to pdf asp net mvc, interview questions on asp net mvc, latest version of asp net mvc, mvc application example asp net c#, mvc vs net core, net mvc datepicker, online asp .net mvc 5 test, pdf viewer asp net mvc, signalr chat application with database in asp net mvc, vb net mvc

Post navigation

Previous Previous post: ASP.NET membership: System.Web.Security. SqlRoleProvider problems
Next Next post: Generate expiring urls for Amazon S3 via a WordPress Plugin

Related Posts

  • What’s next for JavaScript frameworks in 2026

    #​770 — January 27, 2026 Read on the Web JavaScript Weekly Introducing LibPDF: PDF Parsing and Generation from TypeScript — LibPDF bills itself as ‘the PDF library TypeScript deserves’ and supports parsing, modifying, signing and generating PDFs with a modern API in Node, Bun, and the browser. GitHub repo. Documenso JavaScript Frameworks – Heading into 2026

    Posted by Posted on January 27, 2026
    0
  • require(esm) now stable in Node 25

    #​608 — January 22, 2026 Read on the Web Node.js 25.4.0 (Current) Released — Another gradual step forward for Node with require(esm) now marked as stable, as well as the module compile cache, along with a variety of other minor tweaks. Joyee Cheung of the Node team has written a thread on Bluesky going deeper

    Posted by Posted on January 22, 2026
    0
  • A big week for jQuery

    #​769 — January 20, 2026 Read on the Web JavaScript Weekly jQuery 4.0 Released — 20 years on from its original release, the ever-popular (in terms of actual usage) library reaches 4.0 with a migration to ES modules (compatible with modern build tools) along with dropping support for IE 10 and older. With jQuery being

    Posted by Posted on January 20, 2026
    0
  • A new guide to configuring Node packages

    #​607 — January 15, 2026 Read on the Web ⚠️ The Node.js January 13, 2026 Security Releases — Originally expected in December, these releases (of Node.js 25.3.0, 24.13.0, 22.22.0, and 20.20.0) finally landed this week, largely due to their complexity and the scope of the vulnerabilities they tackle. More on that in the next item! The Node.js

    Posted by Posted on January 15, 2026
    0
  • Can we ever fix the web dependency mess?

    #​768 — January 13, 2026 Read on the Web JavaScript Weekly Web Dependencies are Broken; Can We Fix Them? — Lea, who has worked at the heart of Web Standards for years, delivers a compelling (and educational) call to action about a problem every JavaScript developer has encountered: why is managing dependencies and introducing them

    Posted by Posted on January 13, 2026
    0
  • The story of how require(esm) became stable

    #​606 — January 8, 2026 Read on the Web 🎉 Happy New Year! Also, a quick reminder that Node Weekly is now sent every Thursday as part of a reshuffle for many of our newsletters. __Your editor, Peter Cooper npm to Implement ‘Staged Publishing’ After Turbulent Shift Off Classic Tokens — 2025 was a tricky year

    Posted by Posted on January 8, 2026
    0
Judy Alvarez

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Codepolice

  • Github
  • Atlassian
  • Flatlogic
  • Xero
  • Jetbrains
  • Figma
  • What’s next for JavaScript frameworks in 2026
  • require(esm) now stable in Node 25
  • A big week for jQuery
  • A new guide to configuring Node packages
  • Can we ever fix the web dependency mess?
https://flatlogic.com/generator
COPYRIGHT © 2026 - Codepolice