<?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 : POCO</title><link>http://blogs.msdn.com/efdesign/archive/tags/POCO/default.aspx</link><description>Tags: POCO</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Self-Tracking Entities in the Entity Framework</title><link>http://blogs.msdn.com/efdesign/archive/2009/03/24/self-tracking-entities-in-the-entity-framework.aspx</link><pubDate>Tue, 24 Mar 2009 04:50:52 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9503127</guid><dc:creator>efdesign</dc:creator><slash:comments>67</slash:comments><comments>http://blogs.msdn.com/efdesign/comments/9503127.aspx</comments><wfw:commentRss>http://blogs.msdn.com/efdesign/commentrss.aspx?PostID=9503127</wfw:commentRss><description>&lt;p class="MsoNormal"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="font-size: 14pt; line-height: 115%; mso-bidi-font-size: 11.0pt"&gt;Background &lt;/span&gt;&lt;/b&gt;    &lt;p mce_keep="true"&gt;&lt;/p&gt; &lt;/p&gt; One of the biggest pieces of feedback we received from the &lt;a href="http://blogs.msdn.com/efdesign/archive/2008/11/20/n-tier-improvements-for-entity-framework.aspx" mce_href="http://blogs.msdn.com/efdesign/archive/2008/11/20/n-tier-improvements-for-entity-framework.aspx"&gt;N-Tier Improvements for Entity Framework&lt;/a&gt; post as well as other sources was: &amp;#8220;low level APIs are great, but where is the end-to-end architecture for N-tier and the Entity Framework?&amp;#8221;. &lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;This post outlines some of the additional feedback we&amp;#8217;ve received and describes the self-tracking entities architecture that will ship along side of VisualStudio 2010 and .NET Framework 4.0.  &lt;p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;When an application goes multi-tier, there are important &lt;a href="http://www.codeplex.com/AppArchGuide" mce_href="http://www.codeplex.com/AppArchGuide"&gt;architectural decisions&lt;/a&gt; that the application developer makes around how to communicate between tiers. There are a lot of choices, and the choice depends on a variety of conditions. How rapidly is each tier expected to change? How much control is there over each tier? Are their specific protocol, security, or business policy concerns? The answers to these questions often drive the selection of whether to use data transfer objects (DTOs) or DataSets or something different altogether.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="font-size: 14pt; line-height: 115%; mso-bidi-font-size: 11.0pt"&gt;Self-Tracking Entities &lt;/span&gt;&lt;/b&gt;    &lt;p mce_keep="true"&gt;&lt;/p&gt; &lt;/p&gt; Self-tracking entities know how to do their own change tracking regardless of which tier those changes are made on. As an architecture, self-tracking entities falls between DTOs and DataSets and includes some of the benefits of each.   &lt;p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="font-size: 12pt; line-height: 115%; mso-bidi-font-size: 11.0pt"&gt;Drawing from DataSet &lt;/span&gt;&lt;/b&gt;    &lt;p mce_keep="true"&gt;&lt;/p&gt; &lt;/p&gt; DataSet on the client tier is very easy to use because there is no need to track changes separately or maintain any extra data structures that include change tracking information. DataSet takes care of serializing state information for each row of data. On the mid tier, applying the changes stored within a DataSet is straightforward. DataSets have also gained popularity because of the number of tools that work with DataSets, and because they are easily bound to many UI/presentation controls. Since it works in so many scenarios, for many applications there is never a need to transform data outside of a DataSet allowing a single paradigm to be used up and down the stack.  &lt;p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;However, there are disadvantages to DataSets when used as the communication payload between tiers. The first is the cost of getting the data into a serializable format, and the second is that the DataSet serialization format is generally not very interoperable with other languages that are used to expose services. Another disadvantage of using a DataSet is that you can quickly lose the intent of your service call because so many kinds of things can be included in a DataSet. For example, if the service method is declared as:&lt;/p&gt;  &lt;p class="MsoNormal" style="background: #dbe5f1; mso-background-themecolor: accent1; mso-background-themetint: 51"&gt;&lt;span style="font-size: 10pt; background: #dbe5f1; line-height: 115%; font-family: " mso-shading-themecolor:="mso-shading-themecolor:" accent1;="accent1;" mso-shading-themetint:="mso-shading-themetint:" 51?="51?" courier="courier" new?;="new?;"&gt;DataSet GetCustomer(string id); &lt;/span&gt;&lt;/p&gt;  &lt;p mce_keep="true"&gt;&lt;/p&gt; It is extra work to ensure that the DataSet that is returned contains only rows of data that pertain to &amp;#8220;customers&amp;#8221;. It is also more difficult to specify a service contract that says the DataSet is also supposed to return data for each customer&amp;#8217;s orders and their order details.  &lt;p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;Self-tracking entities share many advantages with DataSet. They also encapsulate change tracking information, which is serialized along with the data contained in the entity. On the mid-tier applying changes from a graph of self-tracking entities to a persistent context is equally &lt;a href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=Posts&amp;amp;sectionid=10661&amp;amp;postid=9503077#Midtier" mce_href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=Posts&amp;amp;sectionid=10661&amp;amp;postid=9503077#Midtier"&gt;straightforward&lt;/a&gt;. The Entity Framework will also provide tools for &lt;a href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=Posts&amp;amp;sectionid=10661&amp;amp;postid=9503077#Generating" mce_href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=Posts&amp;amp;sectionid=10661&amp;amp;postid=9503077#Generating"&gt;generating self-tracking entities&lt;/a&gt; and because these entities are just objects, they can be easily made to work with UI/presentation controls.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="font-size: 12pt; line-height: 115%; mso-bidi-font-size: 11.0pt"&gt;Drawing from DTOs &lt;/span&gt;&lt;/b&gt;    &lt;p mce_keep="true"&gt;&lt;/p&gt; &lt;/p&gt; DTOs and SOA are used to give the developer more control over the service contract and payload for tier to tier communication. DTOs themselves do not have behavior, so they are typically very simple classes designed just to provide the needed information to perform a specific service operation. Not only does this provide the opportunity to optimize the wire format (some believe a DTO is all about the wire format), but it makes it possible and easy to capture the intent of each service method. The data contract used with DTOs is typically interoperable which makes it easy to use services that run on different platforms. DTOs also provide a way to separate messaging contracts from the presentation layer, the business logic, and the persistence layer which in many cases creates a maintainable architecture.   &lt;p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;There are disadvantages to using DTOs and the primary one is complexity. DTOs are often hand-crafted to include only the specific information that is needed for an operation. When there is a common pattern for mapping DTOs to entity classes, there are some tools available that will do DTO generation and mapping but it is not always possible. With DTOs, it is up to the developer to decide how to do change tracking on each tier (especially the client) which increases the complexity of the presentation layer. The complexity of the service implementation also increases because the developer is responsible for translating the DTO into entities for doing business logic validation, as well as being able to report changes stored in the DTO to the persistence framework. &lt;/p&gt;  &lt;p class="MsoNormal"&gt;Not only do self-tracking entities share advantages with DataSets as mentioned above, they also share many advantages with DTOs. Self-tracking entities expose a simple and interoperable wire format and it is clear what kinds of data a service method requires or returns. You can also use a self-tracking entity as part of a message. However, self-tracking entities don&amp;#8217;t give quite as much architectural separation as using pure DTOs, but you do gain a less complex solution that requires fewer data transformations. It is important to note that self-tracking entities can be made to be ignorant of any particular persistence framework making them essentially POCO objects. Particular persistence frameworks such as the Entity Framework will have the capabilities to create these entities and interpret the change tracking information when saving changes.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="font-size: 12pt; line-height: 115%; mso-bidi-font-size: 11.0pt"&gt;.NET Framework 3.5SP1 Challenge &lt;/span&gt;&lt;/b&gt;    &lt;p mce_keep="true"&gt;&lt;/p&gt; &lt;/p&gt; With the .NET Framework 3.5SP1, this sort of solution was very hard to implement using the Entity Framework because change tracking was always done by a centralized ObjectContext which contains an ObjectStateManager. In particular, &amp;#8220;reattaching&amp;#8221; to report changes back to the ObjectStateManager was all but impossible without completely shredding your entity graph and applying changes one entity and one relationship at a time. The &lt;a href="http://blogs.msdn.com/efdesign/archive/2008/11/20/n-tier-improvements-for-entity-framework.aspx" mce_href="http://blogs.msdn.com/efdesign/archive/2008/11/20/n-tier-improvements-for-entity-framework.aspx"&gt;new API changes&lt;/a&gt; that are being added to the Entity Framework in .NET Framework 4.0 are enablers for an easier experience of reporting changes back to the ObjectStateManager, making self-tracking entities (as well as other architectures) easier to build.  &lt;p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;a name="Midtier"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="font-size: 14pt; line-height: 115%; mso-bidi-font-size: 11.0pt"&gt;Mid-tier experience &lt;/span&gt;&lt;/b&gt;      &lt;p mce_keep="true"&gt;&lt;/p&gt;   &lt;/a&gt;&lt;/p&gt; &lt;span style="mso-bookmark: midtier"&gt;Using self-tracking entities on the mid-tier is about working with entity graphs and the Entity Framework. The service contract that is used in the following examples contains two simple methods for retrieving a Customer entity graph and applying updates to that entity graph:&lt;/span&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="background: #dbe5f1; margin-bottom: 0pt; line-height: normal; mso-background-themecolor: accent1; mso-background-themetint: 51; mso-layout-grid-align: none"&gt;&lt;span style="mso-bookmark: midtier"&gt;&lt;span style="font-size: 10pt; color: blue; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;interface &lt;/span&gt;&lt;/span&gt;&lt;span style="mso-bookmark: midtier"&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;ICustomerService        &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-bookmark: midtier"&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;{        &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-bookmark: midtier"&gt;&lt;span style="font-size: 10pt; color: #2b91af; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;Customer&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-bookmark: midtier"&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt; GetCustomer(&lt;span style="color: blue"&gt;string&lt;/span&gt; customerID);         &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-bookmark: midtier"&gt;&lt;span style="font-size: 10pt; color: blue; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;bool &lt;/span&gt;&lt;/span&gt;&lt;span style="mso-bookmark: midtier"&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;UpdateCustomer(&lt;span style="color: #2b91af"&gt;Customer&lt;/span&gt; customer);         &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-bookmark: midtier"&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;} &lt;/span&gt;&lt;/span&gt;    &lt;p mce_keep="true"&gt;&lt;/p&gt; &lt;/p&gt; &lt;span style="mso-bookmark: midtier"&gt;The implementation of the GetCustomer service method can be done using an Entity Framework ObjectContext and using LINQ or query builder methods to retrieve the entity you want. In the example below, a query is issued for a particular customer entity and all of the Orders and OrderDetails are included.&lt;/span&gt;  &lt;p&gt;&lt;/p&gt; &lt;span style="mso-bookmark: midtier"&gt;&lt;/span&gt;  &lt;p class="MsoNormal" style="background: #dbe5f1; margin-bottom: 0pt; line-height: normal; mso-background-themecolor: accent1; mso-background-themetint: 51; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; color: blue; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;public&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt; &lt;span style="color: #2b91af"&gt;Customer&lt;/span&gt; GetCustomer(&lt;span style="color: blue"&gt;string&lt;/span&gt; customerID)       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;{      &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;NorthwindEFContext&lt;/span&gt; context = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;NorthwindEFContext&lt;/span&gt;())       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;{       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;var&lt;/span&gt; result = context.Customers.       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;Include(&lt;span style="color: #a31515"&gt;&amp;quot;Orders.OrderDetails&amp;quot;&lt;/span&gt;).       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;Single(c =&amp;gt; c.CustomerID == customerID);       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;return&lt;/span&gt; result;       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;}       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;} &lt;/span&gt;&lt;/p&gt;  &lt;p mce_keep="true"&gt;&lt;/p&gt; &lt;span style="mso-no-proof: yes"&gt;UpdateCustomer is example of how to save the changes that are made to a graph of self-tracking entities. Similar to DataSet, applying these changes to the persistence layer and saving them should be simple. In the below example, a new Entity Framework API, &amp;#8220;ApplyChanges&amp;#8221; is used which understands how to interpret the change tracking information that is stored by each entity and how to tell the ObjectContext&amp;#8217;s ObjectStateManager about those changes. &lt;/span&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="background: #dbe5f1; margin-bottom: 0pt; line-height: normal; mso-background-themecolor: accent1; mso-background-themetint: 51; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; color: blue; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;public&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt; &lt;span style="color: blue"&gt;void &lt;/span&gt;UpdateCustomer(&lt;span style="color: #2b91af"&gt;Customer&lt;/span&gt; customer)       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;{      &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;NorthwindEFContext&lt;/span&gt; context = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;NorthwindEFContext&lt;/span&gt;())       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;{       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;context.Customers.ApplyChanges(customer);       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;context.SaveChanges();       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;}       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;}&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="font-size: 14pt; line-height: 115%; mso-bidi-font-size: 11.0pt"&gt;Client Experience &lt;/span&gt;&lt;/b&gt;    &lt;p mce_keep="true"&gt;&lt;/p&gt; &lt;/p&gt; The client experience when working with self-tracking entities is similar to how you would manipulate any object graph. You can make changes to scalar or complex properties, add or remove references, and add or remove from collections of related entities. The key part of the experience is that tracking changes is hidden from the client because it is done internally on each entity. There is no ObjectContext and there is no extra state that has to be maintained or passed from client to the tier that does persistence.   &lt;p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;In this example, the test first queries for a customer, then deletes one of the orders. The resulting entity graph is sent back to the service tier using &lt;span style="mso-spacerun: yes"&gt;&amp;#160;&lt;/span&gt;the UpdateCustomer method.&lt;/p&gt;  &lt;p class="MsoNormal" style="background: #dbe5f1; margin-bottom: 0pt; line-height: normal; mso-background-themecolor: accent1; mso-background-themetint: 51; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; color: blue; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;public&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; DeleteObjectsTest()       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;{      &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;CustomerServiceClient&lt;/span&gt; client = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;CustomerServiceClient&lt;/span&gt;())       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;{       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;var&lt;/span&gt; customer = client.GetCustomer(&lt;span style="color: #a31515"&gt;&amp;quot;ALFKI&amp;quot;&lt;/span&gt;);       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;customer.Orders.First().Delete();       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;client.UpdateCustomer(customer);       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;}       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; line-height: 115%; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;} &lt;/span&gt;&lt;/p&gt;  &lt;p mce_keep="true"&gt;&lt;/p&gt; &lt;span style="mso-no-proof: yes"&gt;The next test shows how to add a new Order with two OrderDetails to an existing customer. By default, the constructor of a self-tracking entity puts the entity in the &amp;#8220;Added&amp;#8221; state. There are conveience methods on each self-tracking entity to change this state if needed (Delete() and SetUnchanged()). &lt;/span&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="background: #dbe5f1; margin-bottom: 0pt; line-height: normal; mso-background-themecolor: accent1; mso-background-themetint: 51; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; color: blue; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;public&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; AddObjectsTest()       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;{      &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;CustomerServiceClient&lt;/span&gt; client = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;CustomerServiceClient&lt;/span&gt;())       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;{       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;var&lt;/span&gt; customer = client.GetCustomer(&lt;span style="color: #a31515"&gt;&amp;quot;ALFKI&amp;quot;&lt;/span&gt;);       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;customer.Orders.Add(&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Order&lt;/span&gt;() {&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; OrderID = 100,       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;OrderDetails = {       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;OrderDetail&lt;/span&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ProductID = 3,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Quantity = 7       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;OrderDetail&lt;/span&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ProductID = 4,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Quantity = 8       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;}       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; });       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;client.UpdateCustomer(customer);       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;}       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; line-height: 115%; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;} &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="mso-no-proof: yes"&gt;The final example shows that a self-tracking entity graph&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;can contain any number of changes and those changes can be any combination of adds, modifications, and deletes. &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="background: #dbe5f1; margin-bottom: 0pt; line-height: normal; mso-background-themecolor: accent1; mso-background-themetint: 51; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; color: blue; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;public&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; ComplexModificationsTest ()       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;{      &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;CustomerServiceClient&lt;/span&gt; client = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;CustomerServiceClient&lt;/span&gt;())       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;{       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;var&lt;/span&gt; cust = client.GetCustomer(&lt;span style="color: #a31515"&gt;&amp;quot;ALFKI&amp;quot;&lt;/span&gt;);       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: green"&gt;// remove first order - will do cascade in the database        &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;cust.Orders.Remove(cust.Orders.First());       &lt;br /&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: green"&gt;// modify one of the orders          &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;var&lt;/span&gt; order = cust.Orders.Last();         &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;order.RequiredDate = &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now;         &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;order.OrderDetails.Add(         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;OrderDetail&lt;/span&gt;{         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ProductID = 7,&amp;#160; &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;Quantity = 3&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; });&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: green"&gt;// add new order          &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;cust.Orders.Add(&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Order&lt;/span&gt;()           &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;{           &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;OrderID = 100,           &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;OrderDate = &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now,           &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;ShipCity = &lt;span style="color: #a31515"&gt;&amp;quot;Redmond&amp;quot;&lt;/span&gt;,           &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;ShipAddress = &lt;span style="color: #a31515"&gt;&amp;quot;One Microsoft Way&amp;quot;&lt;/span&gt;,           &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;ShipRegion = &lt;span style="color: #a31515"&gt;&amp;quot;WA&amp;quot;&lt;/span&gt;,           &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;ShipPostalCode = &lt;span style="color: #a31515"&gt;&amp;quot;98052&amp;quot;&lt;/span&gt;,           &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;OrderDetails = {           &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;OrderDetail&lt;/span&gt;{           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ProductID = 3,           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Quantity = 7           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },           &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;OrderDetail&lt;/span&gt;{&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ProductID = 4,           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Quantity = 8           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },           &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;}           &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;});           &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;client.UpdateCustomer(cust);           &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;}           &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; line-height: 115%; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;} &lt;/span&gt;        &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;/span&gt;&lt;/span&gt;    &lt;p&gt;&lt;/p&gt; &lt;/p&gt; &lt;a name="Generating"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="font-size: 14pt; line-height: 115%; mso-bidi-font-size: 11.0pt; mso-no-proof: yes"&gt;Generating Self-Tracking Entities &lt;/span&gt;      &lt;p mce_keep="true"&gt;&lt;/p&gt;   &lt;/b&gt;&lt;/a&gt;&lt;span style="mso-no-proof: yes"&gt;Building self-tracking entities should be as easy as using them. We plan to ship a &lt;/span&gt;&lt;a href="http://blogs.msdn.com/efdesign/archive/2009/01/22/customizing-entity-classes-with-t4.aspx" mce_href="http://blogs.msdn.com/efdesign/archive/2009/01/22/customizing-entity-classes-with-t4.aspx"&gt;&lt;span style="mso-no-proof: yes"&gt;T4 template&lt;/span&gt;&lt;/a&gt;&lt;span style="mso-no-proof: yes"&gt; that will do the code generation for creating self-tracking entities from your EDM. This template will show up in the list of available templates when you right click on your model and choose &lt;i style="mso-bidi-font-style: normal"&gt;Add New Artifact Generation Item&lt;/i&gt;. &lt;/span&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;a href="http://blogs.msdn.com/blogfiles/efdesign/WindowsLiveWriter/SelfTrackingEntitiesintheEntityFramework_10506/clip_image002_2.jpg" mce_href="http://blogs.msdn.com/blogfiles/efdesign/WindowsLiveWriter/SelfTrackingEntitiesintheEntityFramework_10506/clip_image002_2.jpg"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="149" alt="clip_image002" src="http://blogs.msdn.com/blogfiles/efdesign/WindowsLiveWriter/SelfTrackingEntitiesintheEntityFramework_10506/clip_image002_thumb.jpg" width="244" border="0" v:shapes="Picture_x0020_1" mce_src="http://blogs.msdn.com/blogfiles/efdesign/WindowsLiveWriter/SelfTrackingEntitiesintheEntityFramework_10506/clip_image002_thumb.jpg" /&gt;&lt;/a&gt;&amp;#160;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="font-size: 14pt; line-height: 115%; mso-bidi-font-size: 11.0pt; mso-no-proof: yes"&gt;Design Notes &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="font-size: 12pt; line-height: 115%; mso-bidi-font-size: 11.0pt; mso-no-proof: yes"&gt;Inside a Self-Tracking Entity &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="mso-no-proof: yes"&gt;There have not been final decisions about what exactly will be included inside of a self-tracking entity, but it is important to track:&lt;/span&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;div class="MsoNormal"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;/span&gt;&lt;span style="mso-no-proof: yes"&gt;The state of the entity, Added, Deleted, Modified, or Unchanged&lt;/span&gt;&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div class="MsoNormal"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;/span&gt;&lt;span style="mso-no-proof: yes"&gt;The original value from reference relationship properties&lt;/span&gt;&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div class="MsoNormal"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;/span&gt;&lt;span style="mso-no-proof: yes"&gt;Adds and removes from collection relationship properties &lt;/span&gt;&lt;/div&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="mso-no-proof: yes"&gt;This information will be included with the data contract of the entity. As part of the code generation of each self-tracking entity, scalar and complex property changes will mark the entity as &amp;#8220;dirty&amp;#8221; meaning that its state will change from Unchanged to Modified. &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="font-size: 12pt; line-height: 115%; mso-bidi-font-size: 11.0pt; mso-no-proof: yes"&gt;Inside ApplyChanges &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="mso-no-proof: yes"&gt;ApplyChanges is a new API on the ObjectContext and ObjectSet classes that attaches an entity graph and interprets the change tracking information stored in each entity. The design &lt;span style="mso-spacerun: yes"&gt;&amp;#160;&lt;/span&gt;for discovering the change tracking information has not yet been finalized, but there are a couple of options available. One would be to code generate an interface as part of the T4 template for self-tracking entities as well as a version of ApplyChanges that knew about the interface. Another option would be fall back to runtime discovery of the particular properties using a convension and some of the new dynamic capabilities of the framework. The thing we want to avoid is causing the self-tracking entity implementation to have a dependency on any of the Entity Framework assemblies. &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="mso-no-proof: yes"&gt;The algorithm that ApplyChanges uses is:&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;/span&gt;&lt;span style="mso-no-proof: yes; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;span style="mso-list: ignore"&gt;1.&lt;span style="font-weight: normal; font-size: 7pt; line-height: normal; font-style: normal; font-variant: normal" times="times" roman??="roman??" new="new"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-no-proof: yes"&gt;Attaching the entity graph to the ObjectContext&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;/span&gt;&lt;span style="mso-no-proof: yes; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;span style="mso-list: ignore"&gt;2.&lt;span style="font-weight: normal; font-size: 7pt; line-height: normal; font-style: normal; font-variant: normal" times="times" roman??="roman??" new="new"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-no-proof: yes"&gt;Changing the state of each entity using the ChangeObjectState API.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;/span&gt;&lt;span style="mso-no-proof: yes; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;span style="mso-list: ignore"&gt;3.&lt;span style="font-weight: normal; font-size: 7pt; line-height: normal; font-style: normal; font-variant: normal" times="times" roman??="roman??" new="new"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-no-proof: yes"&gt;For any reference relationship property, if there is an original value changing the state of the original reference relationship to Deleted and change the state of the current reference relationship to Added. This is done using the ChangeRelationshipState API.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;/span&gt;&lt;span style="mso-no-proof: yes; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;span style="mso-list: ignore"&gt;4.&lt;span style="font-weight: normal; font-size: 7pt; line-height: normal; font-style: normal; font-variant: normal" times="times" roman??="roman??" new="new"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-no-proof: yes"&gt;For any collection relationship property, use the ChangeRelationshipState API to mark any removed relationships as Deleted and to mark any added relationships as Added. &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="font-size: 14pt; line-height: 115%; mso-bidi-font-size: 11.0pt; mso-no-proof: yes"&gt;Summary &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="mso-no-proof: yes"&gt;We&amp;#8217;ve received a lot of feedback and suggestions on how to make developing multi-tier applications easier using the Entity Framework. One of the components of improving this experience is the introduction of an end-to-end architecture around self-tracking entities. We&amp;#8217;d like to hear your feedback on this addition to the Entity Framework, and any other comments you have on the matter of multi-tier development using domain models and entities. &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="mso-no-proof: yes"&gt;Jeff Derstadt&lt;/span&gt;&lt;/b&gt;&lt;span style="mso-no-proof: yes"&gt;,      &lt;br /&gt;&lt;/span&gt;&lt;span style="mso-no-proof: yes"&gt;Dev Lead, Entity Framework Team, Microsoft &lt;/span&gt;&lt;/p&gt;  &lt;p mce_keep="true"&gt;&lt;/p&gt; &lt;em&gt;&lt;b&gt;&lt;span style="font-size: 11pt; font-family: " mso-ascii-theme-font:="mso-ascii-theme-font:" minor-latin;="minor-latin;" mso-hansi-theme-font:="mso-hansi-theme-font:" minor-latin?="minor-latin?" calibri?,?sans-serif?;="calibri?,?sans-serif?;"&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;/span&gt;&lt;/b&gt;&lt;/em&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;em&gt;&lt;b&gt;&lt;span style="font-size: 11pt; color: blue; font-family: " mso-ascii-theme-font:="mso-ascii-theme-font:" minor-latin;="minor-latin;" mso-hansi-theme-font:="mso-hansi-theme-font:" calibri?,?sans-serif?;="calibri?,?sans-serif?;" TEXT-DECORATION:="TEXT-DECORATION:" none;="none;" text-underline:="text-underline:" none?="none?"&gt;this post&lt;/span&gt;&lt;/b&gt;&lt;/em&gt;&lt;/a&gt;&lt;em&gt;&lt;b&gt;&lt;span style="font-size: 11pt; font-family: " mso-ascii-theme-font:="mso-ascii-theme-font:" minor-latin;="minor-latin;" mso-hansi-theme-font:="mso-hansi-theme-font:" minor-latin?="minor-latin?" calibri?,?sans-serif?;="calibri?,?sans-serif?;"&gt;. &lt;/span&gt;&lt;/b&gt;&lt;/em&gt;&lt;span style="font-size: 11pt; font-family: " mso-ascii-theme-font:="mso-ascii-theme-font:" minor-latin;="minor-latin;" mso-hansi-theme-font:="mso-hansi-theme-font:" minor-latin?="minor-latin?" calibri?,?sans-serif?;="calibri?,?sans-serif?;"&gt;&lt;/span&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9503127" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/efdesign/archive/tags/POCO/default.aspx">POCO</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/Self-Tracking+Entities/default.aspx">Self-Tracking Entities</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/T4/default.aspx">T4</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/Templates/default.aspx">Templates</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><item><title>Discussion about API changes necessary for POCO:</title><link>http://blogs.msdn.com/efdesign/archive/2008/08/01/discussion-about-api-changes-necessary-for-poco.aspx</link><pubDate>Fri, 01 Aug 2008 19:24:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8800626</guid><dc:creator>efdesign</dc:creator><slash:comments>20</slash:comments><comments>http://blogs.msdn.com/efdesign/comments/8800626.aspx</comments><wfw:commentRss>http://blogs.msdn.com/efdesign/commentrss.aspx?PostID=8800626</wfw:commentRss><description>&lt;p&gt;Evolving an API to support new requirements, like POCO, while maintaining backward compatibility is challenging. &lt;/p&gt;
&lt;p&gt;The following design discussion from members of the Object Services team illustrates some of the issues and hard calls involved.&lt;/p&gt;
&lt;p&gt;Have a read, and tell us what you think. &lt;/p&gt;
&lt;p&gt;In particular are we missing something, or overstating the importance of something? Let us know...&lt;/p&gt;
&lt;p&gt;Anyway over to &lt;a href="http://blogs.msdn.com/diego" mce_href="http://blogs.msdn.com/diego"&gt;Diego&lt;/a&gt; and Mirek...&lt;/p&gt;
&lt;h3&gt;POCO API Discussion: Snapshot State Management&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;What is in a snapshot?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;In Entity Framework v1 there is a single way for the state manager to learn about changes in entity instances: the change tracking mechanism is set in such a way that the entity instances themselves notify the state manager of any property change. &lt;/p&gt;
&lt;p&gt;This works seamlessly if you use default code-generated classes, and it is also part of the IPOCO contract for developers willing to create their own entity class hierarchies. &lt;/p&gt;
&lt;p&gt;For version 2, we are currently working on a snapshot-based change tracking mechanism that removes the requirement from classes to send notifications, and enables us to provide full POCO support. &lt;/p&gt;
&lt;p&gt;The basic idea with snapshots is that when you start tracking an entity, a copy of its scalar values is made so that at a later point – typically but not always at the moment of saving changes into the database - you can detect whether anything has changed and needs to be persisted. &lt;/p&gt;
&lt;p&gt;&lt;b&gt;The challenge&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;When we created the v1 API, we made a few assumptions that were totally safe with notification-based change tracking but don’t completely prevail in a snapshot change tracking world. &lt;/p&gt;
&lt;p&gt;We now need to choose the right set of adjustments for the API for it to gracefully adapt to the new scenarios we want to support. &lt;/p&gt;
&lt;p&gt;&lt;b&gt;Mainline scenario: SaveChanges() Method&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;In notification-based change tracking, by the time SaveChanges is invoked, the required entity state information is ready to use. &lt;/p&gt;
&lt;p&gt;With snapshot thought, a property by property comparison needs to be computed for each tracked entity just to know whether it is unchanged or modified. &lt;/p&gt;
&lt;p&gt;Once the snapshot comparison has taken place, SaveChanges can proceed normally. &lt;/p&gt;
&lt;p&gt;In fact, assuming the process is triggered implicitly on every call to SaveChanges, a typical unit of work in which the program queries and attaches entities, then modifies and adds new entities, and finally persists the changes to the database, works unmodified with POCO classes: &lt;/p&gt;
&lt;p&gt;Category category = context.Categories.First();&lt;/p&gt;
&lt;p&gt;category.Name = "some new name"; // modify existing entity&lt;/p&gt;
&lt;p&gt;Category newCategory = new Category(); // create a new entity&lt;/p&gt;
&lt;p&gt;newCategory.ID = 2;&lt;/p&gt;
&lt;p&gt;newCategory.Name = "new category";&lt;/p&gt;
&lt;p&gt;context.AddObject("Categories", newCategory); // add a new entity&lt;/p&gt;
&lt;p&gt;context.SaveChanges(); // detects all changes before saving&lt;/p&gt;
&lt;p&gt;Things get more complicated when a user wants to use lower level APIs that deal with state management.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;i&gt;State Manager Public API&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;ObjectStateManager and ObjectStateEntry classes comprise the APIs that you need to deal with if you want to either get input from, or customize the behavior of Entity Framework’s state management in your own code. &lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Typically, you use these APIs if you want to:&lt;/i&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;Query for objects that are already loaded into memory&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Manipulate the state of tracked entities&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Validate state transitions or data just before persisting to the database &lt;/i&gt;&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Etc.&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;i&gt;As the name implies, &lt;b&gt;ObjectStateManager&lt;/b&gt; is Entity Framework’s state manager object, which maintains state and original values for each tracked entity and performs identity management.&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;i&gt;ObjectStateEntries&lt;/i&gt;&lt;/b&gt;&lt;i&gt; represent entities and relationships tracked in the state manager. ObjectStateEntry functions as a wrapper around each tracked entity or relationship and allows you to get its current state (Unchanged, Modified, Added, Deleted and Detached) as well as the current and original values of its properties.&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Needless to say, the primary client for these APIs is the Entity Framework itself. &lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;ObjectStateEntry.State Property&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;The fundamental issue with snapshot is exemplified by this property. &lt;/p&gt;
&lt;p&gt;With notification-based change tracking, the value for the new state is computed on the fly on each notification, and saved to an internal field. Getting the state later only encompasses reading the state from the internal field. &lt;/p&gt;
&lt;p&gt;With snapshot, the state manager no longer gets notifications, and so the actual state at any time depends on the state when the entity began being tracked, whatever state transitions happened, and the current contents of the object. &lt;/p&gt;
&lt;p&gt;&lt;i&gt;Example&lt;/i&gt;: Use ObjectStateEntry to check the current state of the object. &lt;/p&gt;
&lt;p&gt;Category category = context.Categories.First();&lt;/p&gt;
&lt;p&gt;category.Name = "some new name"; // modify existing entity&lt;/p&gt;
&lt;p&gt;ObjectStateEntry entry = context.ObjectStateManager.GetObjectStateEntry(category);&lt;/p&gt;
&lt;p&gt;Console.WriteLine("State of the object: " + entry.State);&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;i&gt;Question #1: What are the interesting scenarios for using the state management API in POCO scenarios?&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Proposed solutions&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;In above example there are two possible behaviors and it's not obvious for us which one is better: &lt;/p&gt;
&lt;p&gt;&lt;b&gt;Alternative 1: Public ObjectStateManager.DetectChanges() Method&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;In the first alternative, computation of the snapshot comparison for the whole ObjectStateManager is deferred until a new ObjectStateManager method called DetectChanges is invoked. DetectChanges would iterate through all entities tracked by a state manager and would detects changes in entity's scalar values, references and collections using a snapshot comparison in order to compute the actual state for each ObjectStateEntry. &lt;/p&gt;
&lt;p&gt;In the example below, the first time ObjectStateEntry.State is accessed, it returns EntityState.Unchanged. In order to get a current state of the "category" entity, we would need to invoke DetectChanges first: &lt;/p&gt;
&lt;p&gt;Category category = context.Categories.First();&lt;/p&gt;
&lt;p&gt;category.Name = "some new name"; // modify existing entity&lt;/p&gt;
&lt;p&gt;ObjectStateEntry entry = context.ObjectStateManager.GetObjectStateEntry(category);&lt;/p&gt;
&lt;p&gt;Console.WriteLine("State of the object: " + entry.State); // Displays "Unchanged"&lt;/p&gt;
&lt;p&gt;context.ObjectStateManager.DetectChanges();&lt;/p&gt;
&lt;p&gt;Console.WriteLine("State of the object: " + entry.State); // Displays "Modified"&lt;/p&gt;
&lt;p&gt;DetectChanges would be implicitly invoked from within ObjectContext.SaveChanges. &lt;/p&gt;
&lt;p&gt;&lt;b&gt;Pros: &lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;· User knows when detection of changes is performed&lt;/p&gt;
&lt;p&gt;· DetectChanges is a method that user would expect to throw exceptions if some constraint is violated&lt;/p&gt;
&lt;p&gt;· This alternative requires minimal changes in Entity Framework current API implementation&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Cons: &lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;· Since DetectChanges iterates through all the ObjectStateEntries, it is a potentially expensive method&lt;/p&gt;
&lt;p&gt;· User has to remember to explicitly call DetectChanges() before using several methods/properties, otherwise, their result will be inaccurate:&lt;/p&gt;
&lt;p&gt;o ObjectStateEntry.State &lt;/p&gt;
&lt;p&gt;o ObjectStateEntry.GetModifiedProperties() &lt;/p&gt;
&lt;p&gt;o ObjectStateManager.GetObjectStateEntries() &lt;/p&gt;
&lt;p&gt;· This alternative implies adding a new method to ObjectStateManager &lt;/p&gt;
&lt;p&gt;&lt;b&gt;Alternative 2: Private ObjectStateEntry.DetectChanges() Method&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;In the second alternative, there is no public DetectChanges method. Instead, the computation of the current state of an individual entity or relationship is deferred until state of the entry is accessed. &lt;/p&gt;
&lt;p&gt;&lt;b&gt;Pros:&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;· User doesn't have to remember explicitly calling DetectChanges to get other APIs to work correctly&lt;/p&gt;
&lt;p&gt;· Existing API works as expected in positive cases regardless of notification-based or snapshot tracking&lt;/p&gt;
&lt;p&gt;· No new public API is added&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Cons:&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;· The following methods now require additional processing to return accurate results in snapshot:&lt;/p&gt;
&lt;p&gt;o ObjectStateEntry.State&lt;/p&gt;
&lt;p&gt;o ObjectStateEntry.GetModifiedProperties()&lt;/p&gt;
&lt;p&gt;o ObjectStateManager.GetObjectStateEntries() &lt;/p&gt;
&lt;p&gt;· Existing API works differently in negative cases in notification-based and snapshot tracking:&lt;/p&gt;
&lt;p&gt;o some of the existing methods would start throwing exceptions&lt;/p&gt;
&lt;p&gt;&lt;i&gt;or&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;o would require to introduce a new state of an entry – Invalid state (see below for details)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;i&gt;Question #2: What API pattern is better? Having an explicit method to compute the current state based on the snapshot comparisons or having the state to be computed automatically when accessing the state?&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;How this affects other APIs &lt;/b&gt;&lt;/p&gt;
&lt;p&gt;While the State property exemplifies the issue, there are other APIs that would have different behaviors with the two proposed solutions. &lt;/p&gt;
&lt;p&gt;&lt;b&gt;ObjectStateEntry.GetModifiedProperties() Method&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;GetModifiedProperties returns the names of the properties that have been modified in an entity. Similar to the State property, with notification-based change tracking, an internal structure is modified on the fly on each notification. Producing the list later on only encompasses iterating through that structure. &lt;/p&gt;
&lt;p&gt;With snapshot, the state manager no longer gets notifications, and at any given point in time, the actual list of modified properties really depends on a comparison between the original value and the current value of each property. &lt;/p&gt;
&lt;p&gt;Therefore, for alternative #1, this APIs will potentially return wrong results unless it is invoke immediately after DetectChanges. For alternative #2, the behavior would be always correct. &lt;/p&gt;
&lt;p&gt;&lt;b&gt;ObjectStateManager.GetObjectStateEntries()&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;This is the case in which an implementation detail that was a good idea for notification-based change tracking stops offering performance benefits in snapshot. Internally, ObjectStateManager stores ObjectStateEntires in separate dictionaries depending on their state. But in snapshot, any unchanged or modified entity can become deleted because of a referential integrity constraint, and any unmodified entity can become modified. &lt;/p&gt;
&lt;p&gt;In alternative #1, DetectChanges would iterate thought the whole contents of the ObjectSateManager, and thus it would update the internal dictionaries. Once this it done, it becomes safe to do in-memory queries using GetObjectStateEntires the same way it is done today. &lt;/p&gt;
&lt;p&gt;In alternative #2, GetObjectStateEntires would need to look in unchanged, modified and deleted storage when asked for deleted entries; also in unchanged and modified storage when asked for modified entities. &lt;/p&gt;
&lt;p&gt;&lt;b&gt;Querying with MergeOption.PreserveChanges &lt;/b&gt;&lt;/p&gt;
&lt;p&gt;In Entity Framework, MergeOptions is a setting that changes the behavior of a query with regards to its effects on the state manager. Of all the possibilities, PreserveChanges requires an entity to be in the Unchanged state in order to overwrite it with values coming from the database. In order for PreserveChanges to work correctly, accurate information on the actual state of entities is needed. &lt;/p&gt;
&lt;p&gt;Therefore, with alternative #1, querying with PreserveChanges will not have a correct behavior unless it is done immediately after invoking DetectChanges. For alternative #2, querying with PreserverChanges would behavior correctly at any time. &lt;/p&gt;
&lt;p&gt;&lt;b&gt;Referential Integrity constraints&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;When there is a referential integrity constraint defined in the model, a dependent entity may become deleted if the principal entity or the relationship with the principal entity becomes deleted. &lt;/p&gt;
&lt;p&gt;For alternative #1, DetectChanges would also trigger Deletes to propagate downwards throw all referential integrity constraints. &lt;/p&gt;
&lt;p&gt;For alternative #2, finding out the current state of an entity that is dependent in a RIC would requires traversing the graph upwards to find if either the principal entity or a relationship has been deleted. &lt;/p&gt;
&lt;p&gt;&lt;b&gt;Mixed Mode Change Tracking&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;At the same time we are working on snapshot change tracking, we are also working on another feature, denominated dynamic proxies. This feature consists of Entity Framework automatically creating derived classes of POCOs that override virtual properties. Overriding properties enables us to inject automatic lazy loading on property getters, and notifications for notification-based change tracking in property setters. This introduces a subtle scenario: when using proxies, it is possible that: &lt;/p&gt;
&lt;p&gt;a. Not all properties in the class are declared virtual. The remaining properties need to still be processed using snapshot. &lt;/p&gt;
&lt;p&gt;b. Sometimes, non-proxy instances of POCOs and proxy instances of the same type have to coexist in the same ObjectStateManager. For the former, it will have to use snapshot tracking. For thelatter, a combination of snapshot and notifications. &lt;/p&gt;
&lt;p&gt;All in all, it becomes clear that the actual state of an entity does not entirely depend on the value of the internal state field, nor on the snapshot comparison, but on a combination of both. &lt;/p&gt;
&lt;p&gt;&lt;b&gt;ObjectStateEntry.SetModified()&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;As with mixed mode change tracking, SetModified() requires a combination of the internal state and the snapshot comparison to return valid results. &lt;/p&gt;
&lt;p&gt;&lt;b&gt;Handling of invalid states&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;When working in notification-based change tracking, Entity Framework throws exceptions as soon it learns that entity key values has been modified. With the default code-generated classes, the exception prevents the change for being accepted. &lt;/p&gt;
&lt;p&gt;For alternative #1, DetectChanges can throw exceptions if some model constraint (i.e. key immutability) is violated. It is too late to prevent the value from changing. &lt;/p&gt;
&lt;p&gt;&lt;i&gt;Example&lt;/i&gt;: &lt;/p&gt;
&lt;p&gt;Category category = context.Categories.First();&lt;/p&gt;
&lt;p&gt;category.ID = 123;&amp;nbsp; // Modify a key property. This would throw if category wasn't a POCO class.&lt;/p&gt;
&lt;p&gt;context.ObjectStateManager.DetectChanges(); // Throws because key property change was detected.&lt;/p&gt;
&lt;p&gt;For alternative #2, reading the state of modified properties from an entity with modified keys could throw an exception: &lt;/p&gt;
&lt;p&gt;&lt;i&gt;Example:&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;Category category = context.Categories.First();&lt;/p&gt;
&lt;p&gt;category.ID = 123;&amp;nbsp; // Modify a key property. This would throw if category wasn't a POCO class.&lt;/p&gt;
&lt;p&gt;ObjectStateEntry entry = context.ObjectStateManager.GetObjectStateEntry(category);&lt;/p&gt;
&lt;p&gt;Console.WriteLine("State of the object: " + entry.State); &lt;/p&gt;
&lt;p&gt;// Throws because key property change was detected.&lt;/p&gt;
&lt;p&gt;Getting an exception thrown here would be unexpected. But there is an alternative design that is to define a new EntityState that indicates that an entity is &lt;b&gt;Invalid&lt;/b&gt;. This new state would account for the fact that POCO classes per se do not enforce immutable keys. &lt;/p&gt;
&lt;p&gt;Since EntityState is a flag enum, Invalid could be potentially combined with other states. &lt;/p&gt;
&lt;p&gt;SaveChanges would still need to throw an exception if any entity in the state manager is invalid. &lt;/p&gt;
&lt;p&gt;It would be possible to query the state manager for entities in the Invalid state using GetObjectStateEntries method. &lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;i&gt;Question #3: Is it better to have an Invalid state for entries or should the state manager just throw exceptions immediately every time it finds a change on a key?&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;i&gt;&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Our questions:&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;i&gt;1.&lt;/i&gt;&lt;/b&gt;&lt;i&gt; What are the interesting scenarios for using the state management API in POCO scenarios?&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;i&gt;2.&lt;/i&gt;&lt;/b&gt;&lt;i&gt; What API pattern is better? Having an explicit method to compute the current state based on the snapshot comparisons or having the state to be computed automatically when accessing the state?&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;i&gt;3.&lt;/i&gt;&lt;/b&gt;&lt;i&gt; Is it better to have an Invalid state for entries or should the state manager just throw exceptions immediately every time it finds a change on a key?&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;---&lt;/p&gt;
&lt;p&gt;We really want to hear your thoughts on the above questions.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/alexj" mce_href="http://blogs.msdn.com/alexj"&gt;&lt;b&gt;Alex James&lt;/b&gt;&lt;/a&gt; &lt;br&gt;Program Manager, &lt;br&gt;Entity Framework Team&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;b&gt;&lt;i&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;this post&lt;/a&gt;&lt;/i&gt;&lt;/b&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=8800626" 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/Evolving+APIs/default.aspx">Evolving APIs</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/Entity+Framework+4/default.aspx">Entity Framework 4</category></item><item><title>Initial POCO Design Screencast</title><link>http://blogs.msdn.com/efdesign/archive/2008/06/24/initial-poco-design-screencast.aspx</link><pubDate>Wed, 25 Jun 2008 04:36:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8650131</guid><dc:creator>dpblogs</dc:creator><slash:comments>11</slash:comments><comments>http://blogs.msdn.com/efdesign/comments/8650131.aspx</comments><wfw:commentRss>http://blogs.msdn.com/efdesign/commentrss.aspx?PostID=8650131</wfw:commentRss><description>&lt;P&gt;Two guys on the team knocked out&amp;nbsp;&lt;A class="" href="http://download.microsoft.com/download/0/1/f/01fd992a-9c5e-4a33-83a1-56efe19a36b7/POCO%20ChangeTracker.wmv" mce_href="http://download.microsoft.com/download/0/1/f/01fd992a-9c5e-4a33-83a1-56efe19a36b7/POCO ChangeTracker.wmv"&gt;this&lt;/A&gt; quick screencast of some of the prototype work we've been doing around POCO an the State Manager. It's not a long or in depth screencast, but we're hoping to inspire some additional feedback. If you prefer to download a copy of the video, you can download a .zip &lt;A class="" href="http://download.microsoft.com/download/0/1/f/01fd992a-9c5e-4a33-83a1-56efe19a36b7/POCO%20ChangeTracker.zip" mce_href="http://download.microsoft.com/download/0/1/f/01fd992a-9c5e-4a33-83a1-56efe19a36b7/POCO ChangeTracker.zip"&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Elisa Flasko&lt;BR&gt;Program Manager, Data Programmability&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8650131" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/efdesign/archive/tags/ADO.NET/default.aspx">ADO.NET</category><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/Entity+Framework+4/default.aspx">Entity Framework 4</category></item><item><title>Initial POCO Design 1-Pager</title><link>http://blogs.msdn.com/efdesign/archive/2008/06/24/initial-poco-design-1-pager.aspx</link><pubDate>Tue, 24 Jun 2008 22:20:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8648559</guid><dc:creator>dpblogs</dc:creator><slash:comments>26</slash:comments><comments>http://blogs.msdn.com/efdesign/comments/8648559.aspx</comments><wfw:commentRss>http://blogs.msdn.com/efdesign/commentrss.aspx?PostID=8648559</wfw:commentRss><description>&lt;P&gt;Here is a raw cut and paste for our POCO 1-Pager. We are currently working through the design and have some prototype work going on and we would like to hear your feedback. Note this is the "feature design 1-Pager" not the "implementation design 1-Pager" we are still looking at the details for the design and at this point would love to hear feedback on the experience plus thought around state mgmt in general. We will post additional design notes for this feature after the upcoming team design meeting.&lt;/P&gt;
&lt;H3&gt;&lt;A class="" title=_Toc201667368 name=_Toc201667368&gt;&lt;/A&gt;&lt;A class="" title=_Toc119343527 name=_Toc119343527&gt;&lt;/A&gt;&lt;A class="" title=_Toc119169067 name=_Toc119169067&gt;&lt;/A&gt;&lt;A class="" title=_Toc22035656 name=_Toc22035656&gt;&lt;/A&gt;1. Overview&lt;/H3&gt;
&lt;P&gt;Persistence Ignorance refers to being able to allow the developer to write and test domain objects in a way that is entirely independent of fundamental requirements and assumptions that may be made by the infrastructure service (in this case, the Entity Framework). Such requirements / assumptions may often include: 
&lt;UL&gt;
&lt;LI&gt;The need to implement a specific interface (for e.g., IPOCO)&lt;/LI&gt;
&lt;LI&gt;Inheritance from a base class&lt;/LI&gt;
&lt;LI&gt;Providing specific constructors&lt;/LI&gt;
&lt;LI&gt;Object Instantiation/Construction requirements – use a specific factory for instance&lt;/LI&gt;
&lt;LI&gt;The need for metadata or mapping class or property Attributes&lt;/LI&gt;
&lt;LI&gt;The need to use specific relationship mechanisms&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;This amounts to being able to use Plain Old CLR Objects (POCO) so that a developer can author their domain objects free of all assumptions and requirements imposed by the framework. Using this approach, once the domain objects are ready to their satisfaction, the developer can use these classes with the Entity Framework in order for relational database access and persistence. 
&lt;H3&gt;2&lt;A class="" title=_Toc201667369 name=_Toc201667369&gt;&lt;/A&gt;. Context&lt;/H3&gt;
&lt;P&gt;While the customization of entity types has always been a goal with Entity Framework, v1 imposed several restrictions/requirements in terms of how the entity types had to be built – for instance, at the minimum, a few interfaces had to be implemented at a minimum: 
&lt;UL&gt;
&lt;LI&gt;IEntityWithRelationships&lt;/LI&gt;
&lt;LI&gt;IEntityWithChangeTracking&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Pure POCO should eliminate the need to implement these interfaces. 
&lt;P&gt;In addition, POCO shouldn’t require the use of attributes that are required to map object members to the C-space. 
&lt;H3&gt;3&lt;A class="" title=_Toc201667373 name=_Toc201667373&gt;&lt;/A&gt;. Design&lt;/H3&gt;
&lt;P&gt;&lt;B&gt;&lt;/B&gt;
&lt;P&gt;When the Entity Framework supports Persistence Ignorance in the form of pure POCO, entity classes that are free of any infrastructure related artifacts can be authored as shown. The following example shows a Customer entity and an Order entity. There is a relationship between Customer and Order – i.e. a Customer can have many Orders. 
&lt;P&gt;O-Space to C-Space mapping is done by convention – i.e. the CLR types of the entities below map to the corresponding entities already defined in the Conceptual Model.&lt;B&gt;&lt;/B&gt;&lt;PRE class=csharpcode&gt;    &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;class&lt;/SPAN&gt; Customer
    {
        &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; _CustomerID;
        &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; _ContactName;
        &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; _City;
        List&amp;lt;Order&amp;gt; _Orders;

        &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; CustomerID
        {
            get { &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; _CustomerID; }
            set { _CustomerID = &lt;SPAN class=kwrd&gt;value&lt;/SPAN&gt;; }
        }

        &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; ContactName
        {
            get { &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; _ContactName; }
            set { _ContactName = &lt;SPAN class=kwrd&gt;value&lt;/SPAN&gt;; }
        }

        &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; City
        {
            get { &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; _City; }
            set { _City = &lt;SPAN class=kwrd&gt;value&lt;/SPAN&gt;; }
        }

        &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; List&amp;lt;Order&amp;gt; Orders
        {
            get { &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; _Orders; }
            set { _Orders = &lt;SPAN class=kwrd&gt;value&lt;/SPAN&gt;; }
        }
    }
&lt;/PRE&gt;&lt;PRE class=csharpcode&gt;    &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;class&lt;/SPAN&gt; Order
    {
        &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; _OrderID;
        Customer _Customer;
        DateTime _OrderDate;

        &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; OrderID
        {
            get { &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; _OrderID; }
            set { _OrderID = &lt;SPAN class=kwrd&gt;value&lt;/SPAN&gt;; }
        }

        &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; Customer CustomerID
        {
            get { &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; _CustomerID; }
            set { _CustomerID = &lt;SPAN class=kwrd&gt;value&lt;/SPAN&gt;; }
        }

        &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; DateTime OrderDate
        {
            get { &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; _OrderDate; }
            set { _OrderDate = &lt;SPAN class=kwrd&gt;value&lt;/SPAN&gt;; }
        }
    }
&lt;/PRE&gt;
&lt;STYLE type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/STYLE&gt;

&lt;P&gt;Once the POCO classes are in place, one can program against them as first class entity objects. 
&lt;P&gt;For instance, query can be used to materialize POCO objects as shown:&lt;PRE class=csharpcode&gt;        var query = from c &lt;SPAN class=kwrd&gt;in&lt;/SPAN&gt; db.Customers.Include(&lt;SPAN class=str&gt;"Orders"&lt;/SPAN&gt;)
                    &lt;SPAN class=kwrd&gt;where&lt;/SPAN&gt; c.City == &lt;SPAN class=str&gt;"London"&lt;/SPAN&gt;
                    select c;
&lt;/PRE&gt;
&lt;STYLE type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/STYLE&gt;

&lt;P&gt;&lt;B&gt;ObjectContext&lt;/B&gt; can be used for CUD operations much like the usage patterns supported today:&lt;PRE class=csharpcode&gt;        Customer customer = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; Customer();
        customer.City = &lt;SPAN class=str&gt;"London"&lt;/SPAN&gt;;
        customer.ContactName = &lt;SPAN class=str&gt;"Steve"&lt;/SPAN&gt;;
        customer.CompanyName = &lt;SPAN class=str&gt;"Acme"&lt;/SPAN&gt;;

        Order order = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; Order();
        order.OrderDate = DateTime.Today;

        customer.Orders.Add(order);

        db.AddObject(&lt;SPAN class=str&gt;"Customers"&lt;/SPAN&gt;, customer);
        db.SaveChanges();
&lt;/PRE&gt;
&lt;STYLE type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/STYLE&gt;

&lt;P&gt;Tim Mallalieu&lt;BR&gt;Program Manager,&lt;BR&gt;Entity Framework Team 
&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;STRONG&gt;&lt;EM&gt;this post&lt;/EM&gt;&lt;/STRONG&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=8648559" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/efdesign/archive/tags/ADO.NET/default.aspx">ADO.NET</category><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/Entity+Framework+4/default.aspx">Entity Framework 4</category></item></channel></rss>