<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Entity Framework Design : N-Tier</title><link>http://blogs.msdn.com/efdesign/archive/tags/N-Tier/default.aspx</link><description>Tags: N-Tier</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Foreign Keys in the Entity Framework</title><link>http://blogs.msdn.com/efdesign/archive/2009/03/16/foreign-keys-in-the-entity-framework.aspx</link><pubDate>Mon, 16 Mar 2009 23:47:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9481955</guid><dc:creator>efdesign</dc:creator><slash:comments>35</slash:comments><comments>http://blogs.msdn.com/efdesign/comments/9481955.aspx</comments><wfw:commentRss>http://blogs.msdn.com/efdesign/commentrss.aspx?PostID=9481955</wfw:commentRss><description>&lt;H3&gt;Background&lt;/H3&gt;
&lt;P&gt;A number of months ago &lt;A href="http://blogs.msdn.com/efdesign/archive/2008/10/27/foreign-keys-in-the-conceptual-and-object-models.aspx" mce_href="http://blogs.msdn.com/efdesign/archive/2008/10/27/foreign-keys-in-the-conceptual-and-object-models.aspx"&gt;we asked&lt;/A&gt; whether Foreign Keys (FKs) in Conceptual and Object models were important.&lt;/P&gt;
&lt;P&gt;The feedback we got indicated that there are a real mix of opinions on the topic. Some people are all for them while others think that FKs pollute the conceptual model. &lt;/P&gt;
&lt;P&gt;The fact that our customers were so divided meant we thought it was important to provide options here. Those who want FKs in their Entities should be able to do so, so they can gain all the benefits that having FKs in your Entities undoubtedly provide. On the other hand customers who are concerned that have FKs in their Entities in someway pollutes their model can continue to use the type of associations we had in .NET 3.5 SP1.&lt;/P&gt;
&lt;P&gt;In the past we've called the .NET 3.5 SP1 style Associations "first class" associations. Which while accurate somehow implies that associations based on FKs in Entities are "second class". In fact when we talked about this new work recently with our MVPs one of the first questions was "are these second class?", which they most definitely are not. &lt;/P&gt;
&lt;P&gt;The fact is these new associations are different but first class nevertheless.&lt;/P&gt;
&lt;H3&gt;So what's been added?&lt;/H3&gt;
&lt;P&gt;In .NET 4.0 we will add support for a new type of association called "FK Associations". &lt;/P&gt;
&lt;P&gt;The way this works is we will allow you to include your FK columns in your entities as "FK properties", and once you have FK Properties in your entity you can create an "FK Association" that is dependent upon those properties. &lt;/P&gt;
&lt;P&gt;Okay so we will have "FK Associations", what are we going to call the older style associations? Obviously saying something like ".NET 3.5 SP1 style Associations" every time isn't ideal. So we are going to call them "Independent Associations".&lt;/P&gt;
&lt;P&gt;The term "Independent Association" resonates for us because they are independently mapped, whereas FK Associations need no mapping, simply mapping the Entity(Set) is sufficient.&lt;/P&gt;
&lt;H3&gt;How do I use an "FK Association"?&lt;/H3&gt;
&lt;P&gt;The real reason so many customers and partners are asking for "FK Associations" is that they significantly simplify some key coding patterns. So much so that we are convinced that for most people "FK Associations" will be an automatic choice going forward.&lt;/P&gt;
&lt;P&gt;Some of the things that are hard with "Independent Associations" are trivially easy using FK Associations. Scenarios as diverse as DataBinding, Dynamic Data, Concurrency Control,&amp;nbsp; ASP.NET MVC Binders, N-Tier etc are all positively impacted.&lt;/P&gt;
&lt;P&gt;Let's have a look at some code snippets that will work with "FK Associations":&lt;/P&gt;
&lt;P&gt;1) Create a new Product and FK Association to an existing Category by setting the FK Property directly:&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN-BOTTOM: 0pt" class=MsoNormal&gt;&lt;SPAN style="COLOR: blue; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;using&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt; (&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; context = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Context&lt;/SPAN&gt;()) &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;{ &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;//Create a product and a relationship to a known category by ID &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Product&lt;/SPAN&gt; p = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Product &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{ &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;ID = 1, &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Name = &lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"Bovril"&lt;/SPAN&gt;, &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;CategoryID = 13 &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;};&amp;nbsp; &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;//Add the product (and create the relationship by FK value) &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;context.Products.AddObject(p); &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;context.SaveChanges(); &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;This sort of approach works both for insert and update, and is particular useful for things like databinding, where you often have the new Value of the FK in a grid or something but you don't have the corresponding object, and you don't want to wear the cost of a query to pull back the principal object (i.e. the Category).&lt;/P&gt;
&lt;P&gt;2) Create a new Product and a new FK Association to an existing Category by setting the reference instead:&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN-BOTTOM: 0pt" class=MsoNormal&gt;&lt;SPAN style="COLOR: blue; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;public&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; Create_new_Product_in_existing_Category_by_reference() &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;{ &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; (&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; context = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Context&lt;/SPAN&gt;()) &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{ &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;//Create a new product and relate to an existing category &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Product&lt;/SPAN&gt; p = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Product &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{ &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;ID = 1, &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Name = &lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"Bovril"&lt;/SPAN&gt;, &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Category = context.Categories &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .Single(c =&amp;gt; c.Name == &lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"Food"&lt;/SPAN&gt;) &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}; &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// Note: no need to add the product, because relating &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN style="COLOR: green"&gt;&amp;nbsp; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// to an existing category does that automatically. &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// Also notice the use of the Single() query operator&amp;nbsp; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// this is new to EF in .NET 4.0 too. &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;context.SaveChanges(); &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;} &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;} &lt;BR&gt;&lt;BR&gt;This programming pattern is not new to the Entity Framework, you could do this in .NET 3.5 SP1. I called it out because it shows you can still write the sort of code you write with Independent Associations even when using FK Associations.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;3) Update an existing Product without informing the Entity Framework about the original value of the CategoryID (not supported with Independent Associations):&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN-BOTTOM: 0pt" class=MsoNormal&gt;&lt;SPAN style="COLOR: blue; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN-BOTTOM: 0pt" class=MsoNormal&gt;&lt;SPAN style="COLOR: blue; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;public&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; Edit(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Product&lt;/SPAN&gt; editedProduct) &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;{ &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; (&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; context = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Context&lt;/SPAN&gt;()) &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{ &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// Create a stand-in for the original entity &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// by just using the ID. Of the editedProduct &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// Note: you don't have to provide an existing Category or CategoryID &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;context.Products.Attach( &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Product&lt;/SPAN&gt; { ID = editedProduct.ID }); &lt;BR&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// Now update with new values including CategoryID &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;context.Products.ApplyCurrentValues(editedProduct); &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;context.SaveChanges(); &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;} &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;In this example "editedProduct" is a product which has been edited somewhere, this is exactly the sort of the code you might write in the Edit method of a ASP.NET MVC controller, and is a great improvement over the code you have to write using Independent Associations.&lt;/P&gt;
&lt;P&gt;There is much more you can do with FK Associations, but these 3 samples give you a flavor of the sort of coding patterns FK Associations allow. &lt;/P&gt;
&lt;H4&gt;Keeping FKs and References in Sync&lt;/H4&gt;
&lt;P&gt;One thing that hasn't been mentioned so far is that the Entity Framework tries to keep related References and FKs in sync as much as possible. &lt;/P&gt;
&lt;P&gt;When this synchronization occurs depends upon when the Entity Framework is notified of changes, which depends upon the type of Entity Classes involved: be they POCO with Proxies, POCO without Proxies, IPOCO or EntityObjects etc. &lt;/P&gt;
&lt;P&gt;Another post will cover this in more detail.&lt;/P&gt;
&lt;H3&gt;How do I create an "FK Association"?&lt;/H3&gt;
&lt;P&gt;There are a number of ways. &lt;/P&gt;
&lt;P&gt;One mainline scenario is when using the tools to infer a model from a database. We have added an option to choose whether "FK Associations" or "Independent Associations" are generated by default. The same is true if you use EdmGen.exe (i.e. our command line tool).&lt;/P&gt;
&lt;P&gt;The second mainline scenario for creating FK Associations is creating a model from scratch, aka &lt;A href="http://blogs.msdn.com/efdesign/archive/2008/09/10/model-first.aspx" mce_href="http://blogs.msdn.com/efdesign/archive/2008/09/10/model-first.aspx"&gt;Model First&lt;/A&gt; which is new to .NET 4.0.&lt;/P&gt;
&lt;P&gt;Here are the steps involved:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Create two Entities (say Product and Category) that look something like this: &lt;BR&gt;&lt;BR&gt;&lt;A href="http://blogs.msdn.com/blogfiles/efdesign/WindowsLiveWriter/ForeignKeysintheEntityFramework_D970/ProductCategoryStep1.jpg" mce_href="http://blogs.msdn.com/blogfiles/efdesign/WindowsLiveWriter/ForeignKeysintheEntityFramework_D970/ProductCategoryStep1.jpg"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" border=0 alt=ProductCategoryStep1 src="http://blogs.msdn.com/blogfiles/efdesign/WindowsLiveWriter/ForeignKeysintheEntityFramework_D970/ProductCategoryStep1_thumb.jpg" width=455 height=158 mce_src="http://blogs.msdn.com/blogfiles/efdesign/WindowsLiveWriter/ForeignKeysintheEntityFramework_D970/ProductCategoryStep1_thumb.jpg"&gt;&lt;/A&gt; &lt;/LI&gt;
&lt;LI&gt;Add a property that will be the FK Property: i.e. CategoryID &lt;BR&gt;&lt;BR&gt;&lt;A href="http://blogs.msdn.com/blogfiles/efdesign/WindowsLiveWriter/ForeignKeysintheEntityFramework_D970/ProductCategoryStep2.jpg" mce_href="http://blogs.msdn.com/blogfiles/efdesign/WindowsLiveWriter/ForeignKeysintheEntityFramework_D970/ProductCategoryStep2.jpg"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" border=0 alt=ProductCategoryStep2 src="http://blogs.msdn.com/blogfiles/efdesign/WindowsLiveWriter/ForeignKeysintheEntityFramework_D970/ProductCategoryStep2_thumb.jpg" width=495 height=227 mce_src="http://blogs.msdn.com/blogfiles/efdesign/WindowsLiveWriter/ForeignKeysintheEntityFramework_D970/ProductCategoryStep2_thumb.jpg"&gt;&lt;/A&gt; &lt;/LI&gt;
&lt;LI&gt;Create an association between the two EntityTypes with the correct end multiplicities and NavigationProperty names: &lt;BR&gt;&lt;BR&gt;&lt;A href="http://blogs.msdn.com/blogfiles/efdesign/WindowsLiveWriter/ForeignKeysintheEntityFramework_D970/ProductCategoryStep3.jpg" mce_href="http://blogs.msdn.com/blogfiles/efdesign/WindowsLiveWriter/ForeignKeysintheEntityFramework_D970/ProductCategoryStep3.jpg"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" border=0 alt=ProductCategoryStep3 src="http://blogs.msdn.com/blogfiles/efdesign/WindowsLiveWriter/ForeignKeysintheEntityFramework_D970/ProductCategoryStep3_thumb.jpg" width=427 height=412 mce_src="http://blogs.msdn.com/blogfiles/efdesign/WindowsLiveWriter/ForeignKeysintheEntityFramework_D970/ProductCategoryStep3_thumb.jpg"&gt;&lt;/A&gt; &lt;BR&gt;&lt;/LI&gt;
&lt;LI&gt;Double Click the line between the two Entities, that represents the Association, and add a Referential Integrity Constraint: &lt;BR&gt;&lt;BR&gt;&lt;A href="http://blogs.msdn.com/blogfiles/efdesign/WindowsLiveWriter/ForeignKeysintheEntityFramework_D970/ProductCategoryStep4.jpg" mce_href="http://blogs.msdn.com/blogfiles/efdesign/WindowsLiveWriter/ForeignKeysintheEntityFramework_D970/ProductCategoryStep4.jpg"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" border=0 alt=ProductCategoryStep4 src="http://blogs.msdn.com/blogfiles/efdesign/WindowsLiveWriter/ForeignKeysintheEntityFramework_D970/ProductCategoryStep4_thumb.jpg" width=374 height=297 mce_src="http://blogs.msdn.com/blogfiles/efdesign/WindowsLiveWriter/ForeignKeysintheEntityFramework_D970/ProductCategoryStep4_thumb.jpg"&gt;&lt;/A&gt; &lt;BR&gt;This is the step that tells the Entity Framework that the CategoryID is an "FK Property" and that the "CategoryProduct" association is an "FK Association". &lt;BR&gt;&lt;BR&gt;&lt;/LI&gt;
&lt;LI&gt;You end up with something that looks like this: &lt;BR&gt;&lt;BR&gt;&lt;A href="http://blogs.msdn.com/blogfiles/efdesign/WindowsLiveWriter/ForeignKeysintheEntityFramework_D970/ProductCategoryStep5.jpg" mce_href="http://blogs.msdn.com/blogfiles/efdesign/WindowsLiveWriter/ForeignKeysintheEntityFramework_D970/ProductCategoryStep5.jpg"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" border=0 alt=ProductCategoryStep5 src="http://blogs.msdn.com/blogfiles/efdesign/WindowsLiveWriter/ForeignKeysintheEntityFramework_D970/ProductCategoryStep5_thumb.jpg" width=476 height=235 mce_src="http://blogs.msdn.com/blogfiles/efdesign/WindowsLiveWriter/ForeignKeysintheEntityFramework_D970/ProductCategoryStep5_thumb.jpg"&gt;&lt;/A&gt;&amp;nbsp; &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;And you are done you've set up an FK Association. Notice that this association doesn't need to be mapped you simply need to make sure you map all the properties of both Entities.&lt;/P&gt;
&lt;P&gt;Very easy.&lt;/P&gt;
&lt;H3&gt;Summary&lt;/H3&gt;
&lt;P&gt;In .NET 4.0 we will add support for FK Properties and FK Associations to the Entity Framework. The existing style Independent Associations will still be possible, but we expect that FK Associations will become most peoples automatic choice because they simplify so many common Entity Framework coding tasks.&lt;/P&gt;
&lt;P&gt;As always we'd love to hear your thoughts on this work.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;&lt;A href="http://blogs.msdn.com/alexj" mce_href="http://blogs.msdn.com/alexj"&gt;Alex James&lt;/A&gt;, &lt;BR&gt;&lt;/B&gt;Program Manager, Entity Framework Team, Microsoft.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;&lt;I&gt;This post is part of the transparent design exercise in the Entity Framework Team. To understand how it works and how your feedback will be used please look at &lt;/I&gt;&lt;/B&gt;&lt;A href="http://blogs.msdn.com/efdesign/archive/2008/06/23/transparency-in-the-design-process.aspx" mce_href="http://blogs.msdn.com/efdesign/archive/2008/06/23/transparency-in-the-design-process.aspx"&gt;&lt;B&gt;&lt;I&gt;this post&lt;/I&gt;&lt;/B&gt;&lt;/A&gt;&lt;B&gt;&lt;I&gt;. &lt;/I&gt;&lt;/B&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9481955" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/efdesign/archive/tags/Entity+Framework/default.aspx">Entity Framework</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/EDM/default.aspx">EDM</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/N-Tier/default.aspx">N-Tier</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/Designer/default.aspx">Designer</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/FKs/default.aspx">FKs</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/Entity+Framework+4/default.aspx">Entity Framework 4</category></item><item><title>N-Tier Improvements for Entity Framework</title><link>http://blogs.msdn.com/efdesign/archive/2008/11/20/n-tier-improvements-for-entity-framework.aspx</link><pubDate>Thu, 20 Nov 2008 08:33:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9127479</guid><dc:creator>efdesign</dc:creator><slash:comments>51</slash:comments><comments>http://blogs.msdn.com/efdesign/comments/9127479.aspx</comments><wfw:commentRss>http://blogs.msdn.com/efdesign/commentrss.aspx?PostID=9127479</wfw:commentRss><description>&lt;P mce_keep="true"&gt;The first version of Entity Framework provides convenient ways to load, manipulate and persist objects and relationships. As with many other O/RMs, Entity Framework has a state manager that tracks every change made. Existing objects are typically loaded first from the database, later modified, and finally the changes are saved back to the store. &lt;/P&gt;
&lt;P&gt;Another feature, full graph serialization, makes it very easy for developers to ship around object graphs representing snapshots of the &lt;B&gt;current state&lt;/B&gt; of the world, across execution boundaries. &lt;/P&gt;
&lt;P&gt;The next version of Entity Framework will also support Persistence Ignorance. Therefore object graphs can now be made of &lt;A href="http://en.wikipedia.org/wiki/Plain_Old_CLR_Object" mce_href="http://en.wikipedia.org/wiki/Plain_Old_CLR_Object"&gt;POCO&lt;/A&gt; instances, which &lt;A href="http://www.pluralsight.com/community/blogs/aaron/archive/2008/05/13/50934.aspx" mce_href="http://www.pluralsight.com/community/blogs/aaron/archive/2008/05/13/50934.aspx"&gt;WCF now also supports&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Nonetheless, there is a task that belongs in any N-Tier application that still requires a great amount of work for developers using EF:&amp;nbsp; decoding messages that represent &lt;B&gt;state changes&lt;/B&gt; performed by the client, meant to be processed or persisted by the service. &lt;/P&gt;
&lt;P&gt;The major pain point in the first version is the number of intricate steps a program needs to perform in order to setup the state manager in the appropriate state according to the changes encoded in the message. For instance, for any but the simplest scenarios, in order to use the basic graph manipulations APIs in ObjectContext, like AddObject and AttachTo, it is necessary to “shred” the object graphs contained in the message, which destroys important information about relationships between object instances that therefore has to be kept somewhere else (as an illustration of this approach, see Danny Simmons’s EntityBag in project &lt;A href="http://code.msdn.microsoft.com/entitybag" mce_href="http://code.msdn.microsoft.com/entitybag"&gt;Perseus&lt;/A&gt;).&lt;/P&gt;
&lt;P&gt;In addition, given that the message typically contains all the necessary information and that concurrency is usually a concern, the program shouldn’t have to re-query the database. Instead, it should be easier to “tell” the state manager about the original state (that came from the database previously) and about what changes were made.&lt;/P&gt;
&lt;P&gt;There are a few approaches to N-Tier that are very popular in the industry. Customers using Entity Framework for the first time often carry the expectation that it will support a similar experience:&lt;/P&gt;
&lt;H3&gt;DataSet &lt;/H3&gt;
&lt;P&gt;The original ADO.NET data access technology includes the DataSet, a versatile data cache that can be serialized as XML and be used to transport collections of rows and relationships and, also &lt;A href="http://msdn.microsoft.com/en-us/library/ms172088(VS.71).aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms172088(VS.71).aspx"&gt;diffgrams&lt;/A&gt; representing changes. &lt;/P&gt;
&lt;P&gt;DataSets make many N-Tier scenarios extremely easy to implement, and over time, have proven helpful for many customers. In spite of this, they are not appropriate for some scenarios and architectural patterns:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;P&gt;The lack of a widely accepted standard serialization format has hindered the development of implementations that could produce or consume datasets in other platforms.&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Diffgrams represent sets of CREATE, UPDATE and DELETE operations of arbitrary depth, which is not adequate for architectural patterns that conceive operations with more constrained semantics (i.e. PlaceOrder, CreateCustomer).&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;No simple ways to control the application of batch CUD operations contained in diffgrams makes them unsuitable any time there is a trust boundary between the client and the server. &lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Also, the data-centered perspective of DataSets leads to an anti-pattern known as the “anemic domain model”, which is characterized by a separation between the data aspect and the behavioral aspect of domain objects.&lt;/P&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;H3&gt;Data Transfer Objects&lt;/H3&gt;
&lt;P&gt;The approach typically used in the DDD and SOA communities to address&amp;nbsp; multi-tier scenarios is to hand-build a service with well defined operation semantics together with the a conceptual message format, usually composed of &lt;A href="http://msdn.microsoft.com/en-us/library/ms978717.aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms978717.aspx"&gt;data transfer objects&lt;/A&gt; (DTOs).&amp;nbsp; Implementing DTOs often also involves writing the logic that translates DTOs back and forth to persistent objects.&lt;/P&gt;
&lt;P&gt;Here is a simplified set of rules that characterizes the use of DTOs: &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;P&gt;Actual entities are not serialized, just DTOs, which are value-only objects (without behavior) are exposed in the boundaries.&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;The client does not depend on the types defined on the server. The shapes of the DTOs are the sole contract, and the types used in the client are for the client only.&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;The context or container is not sent together with the message.&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;The service decides what to do with the contents of the message. It is not the message who decides (as an extreme counter example, imagine a message that tells the service to delete all the contents of the database).&lt;/P&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Those rules are especially important in SOA scenarios, in which the client and the server can be separated by a trust boundary, such as the one that exists between two different companies. &lt;/P&gt;
&lt;P&gt;There are other permutations of layered architectures, though, in which the level of decoupling that DTOs provide may not justify the increased complexity, for example: &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;P&gt;A multi-tier application in which the client is fully trusted.&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;A rich internet application in which an infrastructure service is purely used for data persistence (is by design a CRUD-only service) and therefore types exposed do not contain behavior anyway.&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Any architecture in which the persistence framework is actually used to provide and manage DTOs and not the actual entities. &lt;/P&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;H3&gt;REST&lt;/H3&gt;
&lt;P&gt;&lt;A href="http://msdn.microsoft.com/en-us/data/bb931106.aspx" mce_href="http://msdn.microsoft.com/en-us/data/bb931106.aspx"&gt;ADO.NET Data Services&lt;/A&gt; provides a rich framework that developers can easily use to expose any Entity Data Model as a REST-style resource collection. Simple HTTP verbs like GET, PUT, POST and DELETE are used in combination with URIs to represent CRUD operations against the persistence service.&lt;/P&gt;
&lt;P&gt;This pattern is suitable for many applications and can easily be combined with service operations with richer semantics in the same application. &lt;/P&gt;
&lt;P&gt;ADO.NET Data Services, however, may not be compelling for those customers who want to define their services as operations with richer semantics entirely. &lt;/P&gt;
&lt;H2&gt;Goals&lt;/H2&gt;
&lt;P&gt;ADO.NET Data Services goes a long way addressing the needs of customers doing RESTful services, and so there is no need for us to improve Entity Framework experience on that space.&lt;/P&gt;
&lt;P&gt;With the N-Tier improvements for Entity Framework, we want to address some of the same problem space as DataSet, but we want to avoid the primary issues with it. &lt;/P&gt;
&lt;P&gt;Ideally, we would like to provide building blocks that are appealing for developers building solutions on a wide range of architectures. For instance, we would like to provide fine enough control for DTO proponents, but at the same time reduce the level of pain that those trying to address simpler scenarios experience today. &lt;/P&gt;
&lt;H2&gt;Design&lt;/H2&gt;
&lt;P&gt;If we just wanted to provide a DataSet like experience on top of Entity Framework, the most straightforward (although very expensive to test) way would probably be based on full serialization of the state manager. Basically, the internal representation of ObjectStateManager includes collections of objects to be deleted, inserted, and modified, and also relationships to be added and deleted, as well as objects and relationships that should remain unchanged. &lt;/P&gt;
&lt;P&gt;Such a model would lead to very fine grain control of the state manager, but you would lose some of the benefits of operating on the domain objects and the higher level APIs. For instance, it would make it extremely easy for the program to set the state manager in a completely invalid state.&lt;/P&gt;
&lt;P&gt;An alternative representation for such an experience would be to ship a “change log” containing the history of all operations performed on the client. This representation has the disadvantage of being more verbose than the previous one, but it would make “point in time” rollbacks pretty easy to implement.&lt;/P&gt;
&lt;P&gt;Besides these two, there are a few more interesting generic representations for changes in a graph, but in general, they all suffer from the same disadvantage: providing a solution for them does not give the user the level of control that the most complicated scenarios and sophisticated patterns require. &lt;/P&gt;
&lt;P&gt;Based on this fact, we decided to adopt the following goal for the design: &lt;/P&gt;
&lt;P&gt;&lt;B&gt;Entity Framework won’t define its own unique representation for the set of changes represented in an N-Tier application. Instead, it will provide basic building block APIs that will facilitate the use of a wide range of representations. &lt;/B&gt;&lt;/P&gt;
&lt;P&gt;This has the desirable consequence that Entity Framework won’t impose a pattern for N-Tier. Both DTO-style and DataSet-like experiences can be built on top of a minimal set of building blocks APIs. It is up to the developer to select the pattern that better suits the application.&lt;/P&gt;
&lt;P&gt;Here is a first cut of the new methods that we are proposing to add to the ObjectContext. The new APIs will work with EntityObjects, IPOCO and POCO entities:&lt;/P&gt;
&lt;DIV class=codeblock&gt;&lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt;&lt;SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;partial&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ObjectContext&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;{&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;summary&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; Apply property values to original state of the entity&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="entitySetName"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;name of EntitySet of root&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="original"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;entity with original values&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; ApplyOriginalValues(&lt;SPAN style="COLOR: blue"&gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string&lt;/SPAN&gt; entitySetName, &lt;SPAN style="COLOR: blue"&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; object&lt;/SPAN&gt; original) { }&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;summary&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; Changes the state of the entity and incident relationships &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="entity"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;entity to change state of&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="state"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;new state&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; ChangeObjectState(&lt;SPAN style="COLOR: blue"&gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; object&lt;/SPAN&gt; entity, &lt;SPAN style="COLOR: blue"&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EntityState&lt;/SPAN&gt; state) { }&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;summary&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; Changes state of relationship &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="source"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;source object of relationship&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="target"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;target object of relationship&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="relationshipName"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;name of relationship&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="sourceRole"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;role of source object&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="targetRole"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;role of target object&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt; &amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="state"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;new state&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; ChangeRelationshipState(&lt;SPAN style="COLOR: blue"&gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; object&lt;/SPAN&gt; source, &lt;SPAN style="COLOR: blue"&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; object&lt;/SPAN&gt; target, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; relationshipName, &lt;SPAN style="COLOR: blue"&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string&lt;/SPAN&gt; sourceRole, &lt;SPAN style="COLOR: blue"&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string&lt;/SPAN&gt; targetRole, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;EntityState&lt;/SPAN&gt; state) { } &lt;BR&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;summary&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; Changes state of relationship represented by navigation &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt; property&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="source"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;source object of relationship&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="target"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;target object of relationship&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="navigationProperty"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;navigation property&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="state"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;new state&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; ChangeRelationshipState(&lt;SPAN style="COLOR: blue"&gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; object&lt;/SPAN&gt; source, &lt;SPAN style="COLOR: blue"&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; object&lt;/SPAN&gt; target, &lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string&lt;/SPAN&gt; navigationProperty, &lt;SPAN style="COLOR: blue"&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EntityState&lt;/SPAN&gt; state) { }&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;summary&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; Changes state of relationships represented by lambda &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt; expression&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;typeparam name="TSource"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;type of source entity&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/typeparam&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="source"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;source entity of relationship&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="target"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;target entity of relationship&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="selector"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;property selector expression&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="state"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;new state&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; ChangeRelationshipState&amp;lt;TSource&amp;gt;( &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TSource source, &lt;SPAN style="COLOR: blue"&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; object&lt;/SPAN&gt; target, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Expression&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Func&lt;/SPAN&gt;&amp;lt;TSource, &lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt;&amp;gt;&amp;gt; selector, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;EntityState&lt;/SPAN&gt; state) { }&lt;/SPAN&gt; &lt;BR&gt;&amp;nbsp; &lt;BR&gt;&lt;SPAN&gt;}&lt;/SPAN&gt; &lt;/DIV&gt;
&lt;H3&gt;ApplyOriginalValues&lt;/H3&gt;
&lt;P&gt;Similar to the existing ApplyPropertyChanges, but this API keeps the tracked entity intact, only affecting the corresponding original values. This operation only works for entities in Modified, Unchanged or Deleted states. Added entities by definition don’t have original state.&lt;/P&gt;
&lt;H3&gt;ChangeObjectState&lt;/H3&gt;
&lt;P&gt;This method will transition the state of a tracked entity passed as argument, but will also have side-effects on incident relationships. In case the new state is modified, it will also mark all properties as modified, regardless of the original and current values.&lt;/P&gt;
&lt;H3&gt;ChangeRelationshipState&lt;/H3&gt;
&lt;P&gt;Similar to ChangeObjectState, but sets the relationship between two tracked entities to the provided state. Relationships cannot be in the modified state, but this method can be used to report which relationship should be added, deleted, or unchanged.&lt;/P&gt;
&lt;P&gt;The relationship doesn’t need to exist in the context, but the entities do. If the relationship doesn’t exist, it can be created in the new state. For instance, when this code is invoked, a new relationship can be created between customer1 and order1 in the added state:&lt;/P&gt;
&lt;DIV class=codeblock&gt;&lt;SPAN&gt;context.ChangeRelationship( &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; customer1, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; order1, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c=&amp;gt;c.Orders, &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; EntityState&lt;/SPAN&gt;&lt;SPAN&gt;.Added);&lt;/SPAN&gt; &lt;/DIV&gt;
&lt;P&gt;The relationship is typically represented by the navigation property but the metadata names of the relationship and roles can also be used in a different overload. &lt;/P&gt;
&lt;H3&gt;Design notes&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;All parameters named “entity”, “source” and “target” accept either entities or EntityKeys.&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;We could choose to deprecate the ApplyPropertyChanges API and replace it with ApplyCurrentValues, which is more consistent name-wise with the new ApplyOriginalValues method.&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;For convenience, we should add similar APIs in other types like ObjectStateEntry, RelatedEnd and others as appropriate. For instance, the ObjectStateEntry will also have a ChangeState&amp;nbsp; API that will only take the target state parameter.&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;&lt;?xml:namespace prefix = o /&gt;&lt;o:p&gt;We could choose to put ChangeObjectState() and the various ChangeRelationshipState() in ObjectStateManager rather than in ObjectContext, since this is a lower level API than everything else currently in the ObjectContext.&lt;/o:p&gt;&lt;/P&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;H2&gt;Scenario tests&lt;/H2&gt;
&lt;P&gt;To get a sense of how the new API can be used, we have tried several different approaches and representations. We also have plans to release sample code that will show in more detail different ways to use the new API. In the meanwhile, here are a few simple cases.&lt;/P&gt;
&lt;H3&gt;General purpose Attach with state resolution delegate&lt;/H3&gt;
&lt;P&gt;In this scenario between a client and mid-tier, the intention is to allow a client to query for a Customer entity with the Customer’s Order entities. The client then makes a variety of changes to the Customer entity graph including modifying the Customer, and adding or removing Orders.&amp;nbsp; The client would like to send the updated Customer entity graph to the mid-tier so that it can be processed and persisted. &lt;/P&gt;
&lt;P&gt;This system will use a simple mechanism to help with change tracking on DTO entities. Each DTO will implement a small interface to help determine the state of the entity using three properties: IsNew, IsModified, and IsDeleted. In this example, original values are not tracked by the client.&lt;/P&gt;
&lt;DIV class=codeblock&gt;&lt;SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;public interface&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;IEntityWithChanges&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;{&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;bool&lt;/SPAN&gt; IsNew { &lt;SPAN style="COLOR: blue"&gt;get&lt;/SPAN&gt;; }&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;bool&lt;/SPAN&gt; IsModified { &lt;SPAN style="COLOR: blue"&gt;get&lt;/SPAN&gt;; }&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;bool&lt;/SPAN&gt; IsDeleted { &lt;SPAN style="COLOR: blue"&gt;get&lt;/SPAN&gt;; }&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;}&lt;/SPAN&gt; &lt;/DIV&gt;
&lt;P&gt;When the client makes changes to the Customer entity graph, the only requirement in this scenario is that when an entity changes, the appropriate property will return true to help determine the state of the entity. &lt;/P&gt;
&lt;P&gt;The mid-tier will expose a service method that implements the logic to update the Customer entity graph. Rather than traverse the Customer, her Orders and OrderLines looking for changes, the service method will use a convention based mechanism that knows how to deal with the IEntityWithChanges interfaces. In this scenario, this mechanism takes the form of an extension method to the ObjectContext that will attach an entity graph to the context, and use a delegate to map each entity that implements IEntityWithChanges to an EntityState so that it can be used with the new ChangeObjectState APIs. &lt;/P&gt;
&lt;P&gt;First we can define a method to map from an IEntityWithChanges to an EntityState:&lt;/P&gt;
&lt;DIV class=codeblock&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;summary&amp;gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; A mapping from an IEntityWithChanges to an EntityState&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt;&lt;SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;EntityState&lt;/SPAN&gt; GetEntityState(&lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt; entity)&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;{&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: #2b91af"&gt;IEntityWithChanges&lt;/SPAN&gt; entityWithChanges = &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; entity &lt;SPAN style="COLOR: blue"&gt;as&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;IEntityWithChanges&lt;/SPAN&gt;;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (entityWithChanges != &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;)&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (entityWithChanges.IsNew)&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;EntityState&lt;/SPAN&gt;.Added;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;else&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (entityWithChanges.IsModified)&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;EntityState&lt;/SPAN&gt;.Modified;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;else&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (entityWithChanges.IsDeleted)&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;EntityState&lt;/SPAN&gt;.Deleted;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;EntityState&lt;/SPAN&gt;.Unchanged;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;}&lt;/SPAN&gt; &lt;/DIV&gt;
&lt;P&gt;Next we will define the extension method on an ObjectContext that can attach an entity graph and use a mapping delegate to determine the state of each entity in the graph.&lt;/P&gt;
&lt;DIV class=codeblock&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;summary&amp;gt; &lt;BR&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; Attach a graph of entities using a supplied mapping function to &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; determine the entity's state. &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; In this example, the state of relationships between entities is &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; determined by the rules of ChangeObjectState: &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; - if one entity in the relationship is Added, the relationship is &lt;BR&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; Added &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; - if an entity is Deleted or Detached, all incident relationships &lt;BR&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; are Deleted or Detached &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/summary&amp;gt; &lt;BR&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="entitySetName"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;name of EntitySet of root&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/param&amp;gt; &lt;BR&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="entityGraph"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;graph of entities to attach&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/param&amp;gt; &lt;BR&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="entityStateMap"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;EntityState resolver&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/param&amp;gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt;&lt;SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; Attach( &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this ObjectContext&lt;/SPAN&gt; context, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; entitySetName, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt; entityGraph, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: #2b91af"&gt;Func&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #2b91af"&gt;EntityState&lt;/SPAN&gt;&amp;gt; entityStateMap) &lt;BR&gt;{ &lt;BR&gt;&amp;nbsp;&amp;nbsp; &lt;B&gt;&amp;nbsp;&lt;/B&gt;context.AttachTo(entitySetName, entityGraph); &lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;// Create a list of unique entities in the graph &lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; allEntities = &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; context &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .ObjectStateManager &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .GetObjectStateEntries(EntityState.Unchanged) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .Where(entry =&amp;gt; !entry.IsRelationship) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .Select(entry =&amp;gt; entry.Entity); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;// Apply the entityStateMap to each entity &lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;foreach&lt;/SPAN&gt; (&lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt; entity &lt;SPAN style="COLOR: blue"&gt;in&lt;/SPAN&gt; allEntities) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; context.ChangeObjectState(entity, entityStateMap(entity)); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;}&lt;B&gt;&lt;/B&gt;&lt;/SPAN&gt; &lt;/DIV&gt;
&lt;P&gt;Finally we can define our service method that can update a Customer entity graph using the mapping delegate and the Attach extension method.&lt;/P&gt;
&lt;DIV class=codeblock&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;summary&amp;gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; A service method to update a Customer's entity graph which &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; can include modifications to the Customer entity, &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; new Orders, and removal of Orders&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="c"&amp;gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt;&lt;SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; UpdateCustomerOrder(&lt;SPAN style="COLOR: #2b91af"&gt;Customer&lt;/SPAN&gt; customer)&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;{&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #2b91af"&gt;NorthwindEntities&lt;/SPAN&gt; context = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;NorthwindEntities&lt;/SPAN&gt;())&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;// Call the Attach extenion method with the mapping delegate &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;// that goes from IEntityWithChanges to EntityState&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; context.Attach(&lt;SPAN style="COLOR: #a31515"&gt;"Customers"&lt;/SPAN&gt;, customer, GetEntityState);&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; context.SaveChanges();&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;}&lt;/SPAN&gt; &lt;/DIV&gt;
&lt;H3&gt;&lt;SPAN style="FONT-FAMILY: " color:="COLOR:" calibri?,?sans-serif?;="calibri?,?sans-serif?;" #1f497d?="#1f497d?"&gt;&lt;BR&gt;&lt;/SPAN&gt;ChangeOrder Service Operation&lt;/H3&gt;
&lt;P&gt;In this scenario, the mid-tier exposes a method to perform a very specific operation: changing the Customer that owns an Order. The client can set the Order’s Customer to a new Customer or to one that already exists in the store. In either case, the service method uses the old Customer so that it can remove the relationship between the Order and that Customer.&lt;/P&gt;
&lt;DIV class=codeblock&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;summary&amp;gt; &lt;BR&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; Updates an Order by changing the relationship between the Order &lt;BR&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt; and a Customer in this case &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/summary&amp;gt; &lt;BR&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="updatedOrder"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;order to update&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/param&amp;gt; &lt;BR&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="oldCustomer"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;previous customer&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/param&amp;gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt;&lt;SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; ChangeOrder(&lt;SPAN style="COLOR: #2b91af"&gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Order&lt;/SPAN&gt; updatedOrder, &lt;SPAN style="COLOR: #2b91af"&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Customer&lt;/SPAN&gt; oldCustomer) &lt;BR&gt;{ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #2b91af"&gt;NorthwindEntities&lt;/SPAN&gt; context = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;NorthwindEntities&lt;/SPAN&gt;()) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;// Tell the context about the entities to persist &lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; context.AttachTo(&lt;SPAN style="COLOR: #a31515"&gt;"Orders"&lt;/SPAN&gt;, updatedOrder); &lt;BR&gt;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;// Change the state of the new customer &lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;// In this example, this is done by the convention: &lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;// - Customer.CustomerID is null --&amp;gt; customer is 'Added' &lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;// - Customer.CustomerID is not null --&amp;gt; it already exists &lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt;(updatedOrder.Customer.CustomerID == &lt;SPAN style="COLOR: #a31515"&gt;""&lt;/SPAN&gt;) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;// When state of customer changes to 'Added', state &lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;// of the relationship between updatedOrder and &lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;// pdatedOrder.Customer is also changed to 'Added' &lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; context.ChangeObjectState( &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; updatedOrder.Customer, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: #2b91af"&gt;EntityState&lt;/SPAN&gt;.Added); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;else &lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (updatedOrder.Customer.CustomerID != &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; oldCustomer.CustomerID) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;// only relationship needs to be marked as 'Added' &lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; context.ChangeRelationshipState( &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; updatedOrder, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; updatedOrder.Customer, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; o =&amp;gt; o.Customer, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: #2b91af"&gt;EntityState&lt;/SPAN&gt;.Added); &lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;// Report removal of relationship between &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // pdatedOrder and oldCustomer&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; context.ChangeRelationshipState( &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; updatedOrder, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; oldCustomer, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Customer", &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: #2b91af"&gt;EntityState&lt;/SPAN&gt;.Deleted);&lt;/SPAN&gt; &lt;BR&gt;&amp;nbsp;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;// Persist the changes to the store &lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; context.SaveChanges(); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;}&lt;/SPAN&gt; &lt;/DIV&gt;
&lt;P&gt;As is always the case, your feedback on this topic is welcome! &lt;/P&gt;
&lt;P&gt;Jeff Derstadt &lt;BR&gt;Jaroslaw Kowalski &lt;BR&gt;Diego Vega &lt;BR&gt;and The Object Services Team&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;EM&gt;This post is part of the transparent design exercise in the Entity Framework Team. To understand how it works and how your feedback will be used please look at &lt;/EM&gt;&lt;/STRONG&gt;&lt;A href="http://blogs.msdn.com/efdesign/archive/2008/06/23/transparency-in-the-design-process.aspx" mce_href="http://blogs.msdn.com/efdesign/archive/2008/06/23/transparency-in-the-design-process.aspx"&gt;&lt;FONT color=#4c6d7e&gt;&lt;STRONG&gt;&lt;EM&gt;this post&lt;/EM&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;STRONG&gt;&lt;EM&gt;.&lt;/EM&gt;&lt;/STRONG&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9127479" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/efdesign/archive/tags/Entity+Framework/default.aspx">Entity Framework</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/POCO/default.aspx">POCO</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/ObjectServices/default.aspx">ObjectServices</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/N-Tier/default.aspx">N-Tier</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/Entity+Framework+4/default.aspx">Entity Framework 4</category></item></channel></rss>