<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Codepolice.net &#187; Cascade Delete</title>
	<atom:link href="http://codepolice.net/tag/cascade-delete/feed/" rel="self" type="application/rss+xml" />
	<link>http://codepolice.net</link>
	<description>C#, ASP.NET, MVC, LINQ, Wordpress and stuff like that</description>
	<lastBuildDate>Mon, 26 Jul 2010 08:58:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Cascade delete in Entity Framework</title>
		<link>http://codepolice.net/2008/12/16/cascade-delete-in-entity-framework/</link>
		<comments>http://codepolice.net/2008/12/16/cascade-delete-in-entity-framework/#comments</comments>
		<pubDate>Tue, 16 Dec 2008 09:37:21 +0000</pubDate>
		<dc:creator>Ola</dc:creator>
				<category><![CDATA[Entity Framework]]></category>
		<category><![CDATA[Cascade]]></category>
		<category><![CDATA[Cascade Delete]]></category>
		<category><![CDATA[Delete]]></category>
		<category><![CDATA[Enitity Framework]]></category>
		<category><![CDATA[Model]]></category>

		<guid isPermaLink="false">http://www.codepolice.net/?p=93</guid>
		<description><![CDATA[I hade 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 a item from my database with some childrens. But i got the error A [...]]]></description>
			<content:encoded><![CDATA[<p>I hade 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.</p>
<p>I was trying to delete a item from my database with some childrens. But i got the error</p>
<p><em>A relationship is being added or deleted from an AssociationSet &#8216;FK_ItemChildren_Item&#8217;. With cardinality constraints, a corresponding &#8216;ItemChildren&#8217; must also be added or deleted.</em></p>
<p>I started to google on it and i<a href="http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/984d3c83-ffef-460e-848a-fb8cf993d6bc/"> found this thread in the MSDN forums</a>. 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.</p>
<p>The SSDL part of the edmx file where updated correctly.</p>
<pre class="brush:xml">&lt;Association Name="FK_ItemChildren_Item"&gt;
 &lt;End Role="Item" Type="Model.Store.Item" Multiplicity="1"&gt;
  &lt;OnDelete Action="Cascade" /&gt;
 &lt;/End&gt;
 &lt;End Role="ItemChildren" Type="Model.Store.ItemChildren"
  Multiplicity="*" /&gt;
 &lt;ReferentialConstraint&gt;
 ..
 &lt;/ReferentialConstraint&gt;
&lt;/Association&gt;</pre>
<p>But the CSDL part where not updated:</p>
<pre class="brush:xml">&lt;Association Name="FK_ItemChildren_Item"&gt;
 &lt;End Type="Model.Item" Role="Item" Multiplicity="1"&gt;
  &lt;OnDelete Action="Cascade"&gt;&lt;/OnDelete&gt;
 &lt;/End&gt;
 &lt;End Type="Model.ItemChildren" Role="ItemChildren"
  Multiplicity="*"&gt;
 &lt;/End&gt;
&lt;/Association&gt;</pre>
<p>The line in <strong>&#8220;&lt;OnDelete Action=&#8221;Cascade&#8221;&gt;&lt;/OnDelete&gt;&#8221;</strong> where 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.</p>
<p><strong>UPDATE!</strong></p>
<p>Alexander Muylaert sent me this script via the comments.</p>
<blockquote><p>Thanks for your blog.  I had this issue on a huge model.  Over 180 tables and hundreds of references.  I didn&#8217;t feel like checking all this manually.</p>
<p>I open the edmx file as an xmldocument and executed the following code.  It fixes this issue in batch&#8230;  The code is not cleaned, but I have already lost a complete day and I can&#8217;t afford to waste more time.  I would like to post this, so someone could use this code and post a cleaned version.</p></blockquote>
<pre class="brush:c#">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;
                            }
                        }
                    }
                }
            }
        }
    }
</pre>
]]></content:encoded>
			<wfw:commentRss>http://codepolice.net/2008/12/16/cascade-delete-in-entity-framework/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->