<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet type="text/xsl" href="RSS_xslt_style.asp" version="1.0" ?>
<rss version="2.0" xmlns:WebWizForums="http://syndication.webwiz.co.uk/rss_namespace/">
 <channel>
  <title>DevForce Community Forum : Entity Cloning</title>
  <link>http://www.ideablade.com/forum/</link>
  <description>This is an XML content feed of; DevForce Community Forum : DevForce 2009 : Entity Cloning</description>
  <pubDate>Fri, 10 Apr 2026 21:37:47 -700</pubDate>
  <lastBuildDate>Fri, 21 Aug 2009 12:33:29 -700</lastBuildDate>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Web Wiz Forums 9.69</generator>
  <ttl>360</ttl>
  <WebWizForums:feedURL>www.ideablade.com/forum/RSS_post_feed.asp?TID=1437</WebWizForums:feedURL>
  <image>
   <title>DevForce Community Forum</title>
   <url>http://www.ideablade.com/forum/forum_images/IdeaBlade_logo_tm.png</url>
   <link>http://www.ideablade.com/forum/</link>
  </image>
  <item>
   <title>Entity Cloning : I received an interesting question...</title>
   <link>http://www.ideablade.com/forum/forum_posts.asp?TID=1437&amp;PID=5218#5218</link>
   <description>
    <![CDATA[<strong>Author:</strong> <a href="http://www.ideablade.com/forum/member_profile.asp?PF=482" rel="nofollow">WardBell</a><br /><strong>Subject:</strong> 1437<br /><strong>Posted:</strong> 21-Aug-2009 at 12:33pm<br /><br />I received an interesting question about how to clone an entity. Here's the thread<DIV>-------------------------------</DIV><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><FONT size=3 face=Calibri>We've an entity for which changes cannot be written, they instead cause a new record to be created and the old one to be deactivated.</FONT></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><?: prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><FONT size=3 face=Calibri>Simplest way in my mind was to edit the entity as per usual, then in the&nbsp;Saving event handler&nbsp;check if the entity's changed, convert it into a new entity instead, undo changes on the original, and mark it inactive.</FONT></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><FONT size=3 face=Calibri>Straight forward right?</FONT></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'"><FONT size=2>// in a partial class of the Employee entity<o:p></o:p></FONT></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'"><FONT size=2>if(EntityAspect.EntityState != EntityState.Modified) {<o:p></o:p></FONT></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'"><FONT size=2>&nbsp; // Do something here to generate a new entity based on the current state of this one...<o:p></o:p></FONT></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'"><FONT size=2>&nbsp; // something like:<o:p></o:p></FONT></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'"><FONT size=2>&nbsp; var empClone = this.CloneNew(); // How do I "CloneNew"?</FONT></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'"><FONT size=2>&nbsp; // Revert changes.<o:p></o:p></FONT></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'"><FONT size=2>&nbsp; EntityAspect.RejectChanges();<o:p></o:p></FONT></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'"><FONT size=2>&nbsp; // Deactivate<o:p></o:p></FONT></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'"><FONT size=2>&nbsp; RecordStatusType_fk_ID = (int)EnumRecordStatusType.Inactive;<BR>}<o:p></o:p></FONT></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P><DIV><SPAN style="FONT-FAMILY: 'Calibri','sans-serif'; FONT-SIZE: 11pt; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-ansi-: EN-US; mso-fareast-: EN-US; mso-bidi-: AR-SA">Tried a few routes, all failed miserably. At present it has the code to clone the entity manually, but that just seems super ugly. Was hopeful with the CloneCore method, but that kept the key which I couldn't figure out how to reset to new.</SPAN></DIV><DIV><SPAN style="FONT-FAMILY: 'Calibri','sans-serif'; FONT-SIZE: 11pt; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-ansi-: EN-US; mso-fareast-: EN-US; mso-bidi-: AR-SA">-------------------------</SPAN></DIV><DIV><SPAN style="FONT-FAMILY: 'Calibri','sans-serif'; FONT-SIZE: 11pt; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-ansi-: EN-US; mso-fareast-: EN-US; mso-bidi-: AR-SA"><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d">I think you’ll find what you need in the test example below.<o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"><FONT color=#000000>&nbsp;&nbsp;&nbsp; &#091;</FONT><SPAN style="COLOR: #2b91af">TestMethod</SPAN><FONT color=#000000>&#093;<o:p></o:p></FONT></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"><FONT color=#000000>&nbsp;&nbsp;&nbsp; </FONT><SPAN style="COLOR: blue">public</SPAN><FONT color=#000000> </FONT><SPAN style="COLOR: blue">void</SPAN><FONT color=#000000> CloneEntity1() {<o:p></o:p></FONT></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"><FONT color=#000000>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT><SPAN style="COLOR: blue">var</SPAN><FONT color=#000000> emp = _em1.Employees.First();<o:p></o:p></FONT></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"><FONT color=#000000>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT><SPAN style="COLOR: #2b91af">Assert</SPAN><FONT color=#000000>.IsTrue(!emp.EntityAspect.IsNullEntity);<o:p></o:p></FONT></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"><FONT color=#000000>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT><SPAN style="COLOR: blue">var</SPAN><FONT color=#000000> empClone = (</FONT><SPAN style="COLOR: #2b91af">Employee</SPAN><FONT color=#000000>) (emp </FONT><SPAN style="COLOR: blue">as</SPAN><FONT color=#000000> </FONT><SPAN style="COLOR: #2b91af">ICloneable</SPAN><FONT color=#000000>).Clone();<o:p></o:p></FONT></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"><FONT color=#000000>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT><SPAN style="COLOR: #2b91af">Assert</SPAN><FONT color=#000000>.IsTrue(empClone.EntityAspect.EntityState.IsDetached());<o:p></o:p></FONT></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"><FONT color=#000000>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT><SPAN style="COLOR: #2b91af">Assert</SPAN><FONT color=#000000>.IsTrue(empClone.EntityAspect.EntityKey == emp.EntityAspect.EntityKey);<o:p></o:p></FONT></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"><o:p><FONT color=#000000>&nbsp;</FONT></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"><FONT color=#000000>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT><SPAN style="COLOR: blue">try</SPAN><FONT color=#000000> {<o:p></o:p></FONT></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"><FONT color=#000000>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; empClone.EntityAspect.AddToManager();<o:p></o:p></FONT></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"><FONT color=#000000>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT><SPAN style="COLOR: #2b91af">Assert</SPAN><FONT color=#000000>.Fail(</FONT><SPAN style="COLOR: #a31515">"shouldn't get here"</SPAN><FONT color=#000000>);<SPAN style="FONT-FAMILY: 'Lucida C&#111;nsole'; COLOR: green; FONT-SIZE: 10pt">// because emp is already in cache with this id</SPAN></FONT></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"><FONT color=#000000>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </FONT><SPAN style="COLOR: blue">catch</SPAN><FONT color=#000000> {<o:p></o:p></FONT></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"><FONT color=#000000>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT><SPAN style="COLOR: #2b91af">Assert</SPAN><FONT color=#000000>.IsTrue(empClone.EntityAspect.EntityState.IsDetached());<o:p></o:p></FONT></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"><FONT color=#000000>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<o:p></o:p></FONT></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"><FONT color=#000000>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emp.EntityAspect.EntityManager.GenerateId(empClone, </FONT><SPAN style="COLOR: #2b91af">Employee</SPAN><FONT color=#000000>.IdEntityProperty);<o:p></o:p></FONT></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"><FONT color=#000000>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT><SPAN style="COLOR: #2b91af">Assert</SPAN><FONT color=#000000>.IsTrue(empClone.EntityAspect.EntityKey != emp.EntityAspect.EntityKey);<o:p></o:p></FONT></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"><FONT color=#000000>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; empClone.EntityAspect.AddToManager();<o:p></o:p></FONT></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"><o:p><FONT color=#000000>&nbsp;</FONT></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"><o:p><FONT color=#000000>&nbsp;</FONT></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"><FONT color=#000000>&nbsp;&nbsp;&nbsp; }<o:p></o:p></FONT></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal></o:p></SPAN></P><SPAN style="COLOR: #1f497d"><DIV>&nbsp;</DIV><DIV>Note that the cloned entity is detached and carries the source entity’s key. You give it a new key BEFORE attaching to the EM (you can’t re-assign the key of an attached entity … at least as of release 5.2.2).<o:p></o:p></SPAN></DIV><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d">It does NOT clone the entity’s graph. We will correct the XML documentation that could be construed to suggest we do. It wouldn’t be obvious how we should do it if we wanted to; once you start following the edges of the graph it’s impossible to know where the business semantics would tell you to stop.<o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d">Accordingly, YOU are responsible for attaching any entities that are dependent upon the new clone. <o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d">However, most of the time, you’ll be doing this with leaf nodes and you won’t have to do anything. For example, if I clone an OrderDetail, it will be automatically belong to the parent Order of the source entity … which is probably right. It’s reference to a Product is probably correct too.<o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d">The challenges begin when you clone an Order. It will not have any child OrderDetails. Should it? Should it not? There is no right answer; it depends upon what you want to do.<o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d">If you decide to clone the OrderDetails too, you will have to attach the clones to their new cloned parent Order. You might want to do all this fix-up while all of the clones are detached and then add them to the EM as a group. <o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d">There are lots of potential complexities here as you might imagine. This should get you going. <o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d">Send in the clones </SPAN><SPAN style="FONT-FAMILY: Wingdings; COLOR: #1f497d">J</P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal></SPAN><SPAN style="COLOR: #1f497d"><o:p></o:p></SPAN></P><DIV></SPAN><SPAN style="FONT-FAMILY: 'Calibri','sans-serif'; FONT-SIZE: 11pt; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-ansi-: EN-US; mso-fareast-: EN-US; mso-bidi-: AR-SA"><SPAN style="FONT-FAMILY: 'Calibri','sans-serif'; FONT-SIZE: 11pt; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-ansi-: EN-US; mso-fareast-: EN-US; mso-bidi-: AR-SA">-------------------------</SPAN></SPAN></DIV><DIV><SPAN style="FONT-FAMILY: 'Calibri','sans-serif'; FONT-SIZE: 11pt; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-ansi-: EN-US; mso-fareast-: EN-US; mso-bidi-: AR-SA"><SPAN style="FONT-FAMILY: 'Calibri','sans-serif'; FONT-SIZE: 11pt; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-ansi-: EN-US; mso-fareast-: EN-US; mso-bidi-: AR-SA"><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d">Cool, that's definitely cleaner. Any way to generate the id without passing in the data entity property?<o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d">I'd tried the same using the CloneCore() method, but it gave me an error during the save process having to do with not being able to fix up all the keys.</P><DIV><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><FONT color=#000000>-------------------------</P><DIV></DIV><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal></FONT><o:p></o:p></SPAN></P></SPAN></SPAN><SPAN style="FONT-FAMILY: 'Calibri','sans-serif'; FONT-SIZE: 11pt; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-ansi-: EN-US; mso-fareast-: EN-US; mso-bidi-: AR-SA"><SPAN style="FONT-FAMILY: 'Calibri','sans-serif'; FONT-SIZE: 11pt; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-ansi-: EN-US; mso-fareast-: EN-US; mso-bidi-: AR-SA"><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d">CloneCore is a protected member and an example of the <a href="http://www.dofactory.com/Patterns/PatternTemplate.aspx" target="_blank"><U><FONT color=#800080 size=3 face=Calibri>Template Design Pattern</FONT></U></A>. It is never called directly by consumers of a class. Instead, it is called within a (typically public) member of the base class which incorporates the method as one of the steps within a fixed algorithm. That’s why you call Clone(), not CloneCore().<o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d">It is virtual to your entity in case you want to add additional behavior during cloning.<o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d">Per .NET standard, a Clone() method, when provided, is only accessible through an explicit implementation of the ICloneable interface … which is why you cast to ICloneable to&nbsp;get at it. IdeaBlade.EntityModel.Entity, the base class of your entities, inherits from EntityWrapper which implements Clone() &#091;a pretty simple method as you can see with Reflector&#093; which calls CloneCore().<o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;+++</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>Now I want to talk a bit more about </o:p></SPAN><SPAN style="COLOR: #1f497d">the sequence of steps by which you create a clone of an existing entity and then add it to an EntityManager.<o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d">It turns out that the proper place of AddToManager in the sequence of cloning steps depends upon whether or not the key of your entity is auto-generated.<o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><B><SPAN style="COLOR: #1f497d">CASE A: EntityKey must be <U>generated</U> explicitly<o:p></o:p></SPAN></B></P></o:p></SPAN><SPAN style="COLOR: #1f497d"><DIV>&nbsp;</DIV><DIV>If the key is NOT auto-generated, you are responsible for adjusting it prior to adding the clone to manager. &nbsp;<o:p></o:p></SPAN></DIV><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><B><SPAN style="COLOR: #1f497d"><o:p></o:p></SPAN></B></P><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d">That’s what you see in the code sample that I sent you. <o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-FAMILY: 'Lucida C&#111;nsole'; COLOR: green; FONT-SIZE: 10pt">// Assume empClone.Id == emp.Id == 21<o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Lucida C&#111;nsole'; COLOR: green; FONT-SIZE: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt">emp.EntityAspect.EntityManager.GenerateId(empClone, <SPAN style="COLOR: #2b91af">Employee</SPAN>.IdEntityProperty); </SPAN><SPAN style="FONT-FAMILY: 'Lucida C&#111;nsole'; COLOR: green; FONT-SIZE: 10pt">// (1)</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"><o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; empClone.EntityAspect.AddToManager();</SPAN><SPAN style="FONT-FAMILY: 'Lucida C&#111;nsole'; COLOR: green; FONT-SIZE: 10pt">// (2)</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"><o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d">The Id is reset with a temporary Id&nbsp;in step (1). </SPAN><SPAN style="COLOR: #1f497d">Here is why. The Employee entity’s key is supposed to be &nbsp;generated via special logic involving a counter table in the database; that logic is inscribed in a custom method (typically in the Domain Model project) that implements IIdGenerator (you can read about in the documentation). The call to GenerateId invokes this logic on the client-side and alerts DevForce to keep track of references to this temporary id (e.g., child entities that become associated with this employee parent).<o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><B><SPAN style="COLOR: #1f497d">CASE B: EntityKey is set <U>manually</U> to a value<o:p></o:p></SPAN></B></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d">Sometimes the Id of an entity is the same as another entity. For example, if Employee and Person are in a 1-to-1 relationship with Person as the “parent”, then Person.Id is generated and the key of Employee (say, Employee.PersonId) receives the id of its associated Person entity.&nbsp; The employee clone code might look like this:<o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Lucida C&#111;nsole'; COLOR: green; FONT-SIZE: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Assume person.Id == 21 but personClone.Id has been updated and is now 42;<o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-FAMILY: 'Lucida C&#111;nsole'; COLOR: green; FONT-SIZE: 10pt">// Assume empClone.PersonId == emp.PersonId == 21 ... and we are not fixing that;<o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Lucida C&#111;nsole'; COLOR: green; FONT-SIZE: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt">empClone.PersonId = personClone.Id; </SPAN><SPAN style="FONT-FAMILY: 'Lucida C&#111;nsole'; COLOR: green; FONT-SIZE: 10pt">// (1)</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"><o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; empClone.EntityAspect.AddToManager();</SPAN><SPAN style="FONT-FAMILY: 'Lucida C&#111;nsole'; COLOR: green; FONT-SIZE: 10pt">// (2)</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"><o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d">In step (1) we are changing the Employee’s key from 21 (it’s cloned value) to the new value, 42.<o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d">SUPPOSE we failed to change the cloned Employee’s key in the above examples. That is, we either failed to ask DevForce to generate the key or failed to set it explicitly. Then the cloned Employee would have the same key as the source Employee in cache.<o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d">Therefore, when we call AddToManager we should get an exception because we can’t have two entities in the cache with the same key. Try it … and you will see the exception.<o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d">HOWEVER !!!<o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><B><SPAN style="COLOR: #1f497d">CASE C: EntityKey is auto-generated<o:p></o:p></SPAN></B></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d">In your shop, most of your tables have auto-increment primary key Id fields which means DevForce will auto-generate keys for entities mapped to these tables. The AddToManager code path is different for these entities; it replaces the clone key with a temporary key … whether you’ve set the key or not. Thus, in this sequence<o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; empClone.ID = 21; </SPAN><SPAN style="FONT-FAMILY: 'Lucida C&#111;nsole'; COLOR: green; FONT-SIZE: 10pt">// (1)</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"><o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emp.EntityAspect.EntityManager.GenerateId(empClone, <SPAN style="COLOR: #2b91af">Employee</SPAN>.IdEntityProperty); </SPAN><SPAN style="FONT-FAMILY: 'Lucida C&#111;nsole'; COLOR: green; FONT-SIZE: 10pt">// (2)</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"><o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; empClone.EntityAspect.AddToManager();</SPAN><SPAN style="FONT-FAMILY: 'Lucida C&#111;nsole'; COLOR: green; FONT-SIZE: 10pt">// (3)</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"><o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d">The ID will change three times<o:p></o:p></SPAN></P><P style="TEXT-INDENT: -0.25in; MARGIN: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1" =MsoListParagraph><SPAN style="COLOR: #1f497d; mso-fareast-font-family: Calibri"><SPAN style="mso-list: Ignore">1.<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="COLOR: #1f497d">To 21<o:p></o:p></SPAN></P><P style="TEXT-INDENT: -0.25in; MARGIN: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1" =MsoListParagraph><SPAN style="COLOR: #1f497d; mso-fareast-font-family: Calibri"><SPAN style="mso-list: Ignore">2.<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="COLOR: #1f497d">To a temp id, e.g., -100<o:p></o:p></SPAN></P><P style="TEXT-INDENT: -0.25in; MARGIN: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1" =MsoListParagraph><SPAN style="COLOR: #1f497d; mso-fareast-font-family: Calibri"><SPAN style="mso-list: Ignore">3.<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="COLOR: #1f497d">To another temp id, e.g., -101<o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d">You may conclude for such entities that it is pointless to set the id.<o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d">It follows also that you won’t get an exception if you simply add the clone to the manager … because DevForce ensures it get a unique key before adding the clone to cache.<o:p></o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><B><SPAN style="COLOR: #1f497d">Conclusion:<o:p></o:p></SPAN></B></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d"><o:p>&nbsp;</o:p></SPAN></P><P style="MARGIN: 0in 0in 0pt" =Ms&#111;normal><SPAN style="COLOR: #1f497d">As with entity creation, you must know how the EntityKey is managed before you can clone one and add the clone to the manager.<o:p></o:p></SPAN></P></SPAN></SPAN></DIV></DIV></DIV>]]>
   </description>
   <pubDate>Fri, 21 Aug 2009 12:33:29 -700</pubDate>
   <guid isPermaLink="true">http://www.ideablade.com/forum/forum_posts.asp?TID=1437&amp;PID=5218#5218</guid>
  </item> 
 </channel>
</rss>