<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://consultingblogs.emc.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>Simon Evans' Blog</title><link>http://consultingblogs.emc.com/simonevans/default.aspx</link><description>My blog covers the technology areas I focus on here at EMC Consulting, namely Architecture using the .NET Framework, ASP.NET, WCF, WCF Data Services and Windows Azure

&lt;a href="https://twitter.com/#!/simonevans"&gt; Follow me on twitter @simonevans&lt;/a&gt;</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP3 (Build: 20423.1)</generator><item><title>Implementing the Repository-Mapper-Command pattern using Entity Framework 4</title><link>http://consultingblogs.emc.com/simonevans/archive/2011/02/03/implementing-the-repository-mapper-command-pattern-using-entity-framework-4.aspx</link><pubDate>Thu, 03 Feb 2011 14:40:00 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:18200</guid><dc:creator>simon.evans</dc:creator><slash:comments>4</slash:comments><comments>http://consultingblogs.emc.com/simonevans/comments/18200.aspx</comments><wfw:commentRss>http://consultingblogs.emc.com/simonevans/commentrss.aspx?PostID=18200</wfw:commentRss><description>&lt;p&gt;Back in August last year I blogged about a pattern I’d created for consuming data from Windows Azure table storage which I called the &lt;a href="http://consultingblogs.emc.com/simonevans/archive/2010/08/18/consuming-data-from-windows-azure-table-storage-using-the-repository-mapper-command-pattern.aspx" target="_blank"&gt;Repository-Mapper-Command&lt;/a&gt; pattern (RMC).&lt;/p&gt;  &lt;p&gt;What was less clear about this blog was that this pattern works for many kinds of repository – not just Azure Table Storage. Indeed, the pattern is very suited to any repository accessed using LINQ (IQueryable&amp;lt;T&amp;gt;), such as Entity Framework based repositories, or WCF Data Service repositories.&lt;/p&gt;  &lt;p&gt;This is the first in a series of three posts, where I will show the use of the RMC pattern using a simple domain model persisted using a repository built for the Entity Framework 4 (EF).&lt;/p&gt;  &lt;p&gt;&lt;b&gt;The RMC pattern revisited&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;The premise of the RMC pattern is to separate the &lt;i&gt;implementation&lt;/i&gt; concerns for a Repository into mappers and commands, making the code more testable, maintainable and promoting reuse. A repository calls one or more mappers and commands, where:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;a mapper translates to and from the external facing Domain objects that the repository interface defines and an internal representation of the data as understood within the repository (for example repository may use a WCF Data service proxy of EF generated entities). &lt;/li&gt;    &lt;li&gt;each command executes a single repeatable transactional unit of work against the underlying infrastructure concern. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;b&gt;Refining the pattern implementation based on lessons learnt&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;Since I wrote my previous post describing this pattern and giving an example of how to implement it using Windows Azure table storage, I have worked on other projects that have implemented the same RMC pattern. Working with this patterns on large scale repositories has led to a few refinements in the implementation of the pattern. We found the lots of repositories and commands led to a proliferation of commands, mappers, interfaces and general plumbing code (like exception handlers); while the code was well factored as reusable and testable code, the shear volume of code made the repository implementation feel more bloated and therefore less maintainable than was ideal.&lt;/p&gt;  &lt;p&gt;With these points in mind, I have made the following refactoring points to the code which applies to all implementations of the pattern:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Place all the commands used by a single repository into a single interface (e.g. IPersonCommands) that defines all the commands (as methods) that the repository can execute. For example the PersonRepository would have an IPersonCommands interface. &lt;/li&gt;    &lt;li&gt;Place all commands for one kind of repository (e.g. Entity Framework) in a single class, which implements all the interfaces for each type of repository. For example the class Commands could implement the IPersonCommands and IAddressCommands interface. Any command methods shared between these two interfaces would only be implemented once by the Commands object. &lt;/li&gt;    &lt;li&gt;Implement AutoMapper profiles to reduce mapping code bloat as per &lt;a href="http://consultingblogs.emc.com/owainwragg/archive/2010/12/15/automapper-profiles.aspx" target="_blank"&gt;Owain’s post here&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;Implement a CommandRunner class which provides common exception and logging plumbing to each command the runner executes, and some syntactic sugar to make the repository code more readable (particularly in the case of compensating transactions). &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;b&gt;The Entity Framework 4 EDM&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;Having described the pattern, lets look at an example implementation in EF. Firstly, here is my sample Entity Data Model (EDM):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://consultingblogs.emc.com/blogs/simonevans/image_0C5AF568.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://consultingblogs.emc.com/blogs/simonevans/image_thumb_247E5FC3.png" width="614" height="641" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This simple model has a few features which are representative of many application models:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The person to address association defines:      &lt;ul&gt;       &lt;li&gt;A person is associated with zero to many addresses. &lt;/li&gt;        &lt;li&gt;An address can be associated with one person, or exist independently of the person. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;The person to Email address association defines:      &lt;ul&gt;       &lt;li&gt;A person is associated with zero to many addresses. &lt;/li&gt;        &lt;li&gt;An email address is always associated with a person. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The important point that is commonly overlooked is there are always two ends to the association (as described above). The value of the EDM is that it makes the relationship explicit and clear to understand. The EDM ensures that, however we navigate the model, CRUD will always work.&lt;/p&gt;  &lt;p&gt;The subtle difference between these two associations is the multiplicity on the person to address association indicates that they are both &lt;a href="http://domaindrivendesign.org/node/88" target="_blank"&gt;aggregate root&lt;/a&gt; objects; this means that they can live independently of each other, and therefore have &lt;b&gt;their own repository &lt;/b&gt;class: a PersonRepository and an AddressRepository. However, the Person to Email Address association differs in that the email address is always owned by a person. Therefore it cannot be an aggregate root; an email address can only be surfaced by the associated PersonRepository.&lt;/p&gt;  &lt;p&gt;Because the address can be persisted without a person through its own repository, the address entity needs the addition foreign key scalar property. This is the PersonId highlighted in yellow above. Providing this scalar property enables the address entity to be managed without constant calls to the person entity.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Which flavour of Entity Framework?&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;In my &lt;a href="http://consultingblogs.emc.com/simonevans/archive/2011/01/31/entity-framework-4-implementation-options.aspx" target="_blank"&gt;last post&lt;/a&gt; I covered design decisions as to which approach you should take to using EF. Lets apply that logic to the RMC pattern in EF.&lt;/p&gt;  &lt;p&gt;The EF implementation used in the RMC pattern is stateless (for use within web sites and services), because the Repository pattern provides a stateless API. In the RMC pattern, mappers are only required if there is an impedance mismatch between the Domain objects and repository implementation classes. With EF, these classes are the Entities in the EDM. Mappers are needed if the entity model does not match the domain model. This is often the case, particularly when a system uses multiple infrastructure concerns (e.g. EF for some of the domain model and table storage other parts).&lt;/p&gt;  &lt;p&gt;This example assumes the most complex scenario, where the EF entities do not match the domain model. Based on these characteristics this example therefore uses a “Model first” approach (using the EDM), with mappers mapping between the Domain model and the Entity model. The entity model objects are auto-generated as POCO classes using the CTP 5 T4 modelling template. This means my Entity Model project looks like this in solution explorer:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://consultingblogs.emc.com/blogs/simonevans/image_71AE594E.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://consultingblogs.emc.com/blogs/simonevans/image_thumb_31783FD4.png" width="259" height="155" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;And a type entity generated from the T4 looks like this in code:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:4450ff98-54cf-4b85-ab65-09174e816636" class="wlWriterEditableSmartContent"&gt;&lt;pre style="width:649px;height:550px;background-color:White;overflow:auto;"&gt;&lt;div&gt;&lt;span style="color:#008080;"&gt; 1&lt;/span&gt; &lt;span style="color:#0000FF;"&gt;namespace&lt;/span&gt;&lt;span style="color:#000000;"&gt; EMC.Sample.Data.Entity
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 2&lt;/span&gt; &lt;span style="color:#000000;"&gt;{
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 3&lt;/span&gt; &lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 4&lt;/span&gt; &lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Collections.Generic;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 5&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 6&lt;/span&gt; &lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;partial&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; Person
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 7&lt;/span&gt; &lt;span style="color:#000000;"&gt;    {
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 8&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; Person()
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 9&lt;/span&gt; &lt;span style="color:#000000;"&gt;        {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;10&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;this&lt;/span&gt;&lt;span style="color:#000000;"&gt;.Addresses &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; HashSet&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Address&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;();
&lt;/span&gt;&lt;span style="color:#008080;"&gt;11&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;this&lt;/span&gt;&lt;span style="color:#000000;"&gt;.EmailAddresses &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; HashSet&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;EmailAddress&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;();
&lt;/span&gt;&lt;span style="color:#008080;"&gt;12&lt;/span&gt; &lt;span style="color:#000000;"&gt;        }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;13&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;14&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; Primitive properties&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;15&lt;/span&gt; &lt;span style="color:#008000;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;16&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; Id { &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;get&lt;/span&gt;&lt;span style="color:#000000;"&gt;; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;set&lt;/span&gt;&lt;span style="color:#000000;"&gt;; }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;17&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; Firstname { &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;get&lt;/span&gt;&lt;span style="color:#000000;"&gt;; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;set&lt;/span&gt;&lt;span style="color:#000000;"&gt;; }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;18&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; Surname { &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;get&lt;/span&gt;&lt;span style="color:#000000;"&gt;; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;set&lt;/span&gt;&lt;span style="color:#000000;"&gt;; }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;19&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;20&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; Navigation properties&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;21&lt;/span&gt; &lt;span style="color:#008000;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;22&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;virtual&lt;/span&gt;&lt;span style="color:#000000;"&gt; ICollection&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Address&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; Addresses { &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;get&lt;/span&gt;&lt;span style="color:#000000;"&gt;; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;set&lt;/span&gt;&lt;span style="color:#000000;"&gt;; }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;23&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;virtual&lt;/span&gt;&lt;span style="color:#000000;"&gt; ICollection&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;EmailAddress&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; EmailAddresses { &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;get&lt;/span&gt;&lt;span style="color:#000000;"&gt;; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;set&lt;/span&gt;&lt;span style="color:#000000;"&gt;; }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;24&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;25&lt;/span&gt; &lt;span style="color:#000000;"&gt;    }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;26&lt;/span&gt; &lt;span style="color:#000000;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note how clean this code is – pure auto generated POCO with no dependencies on other libraries or implementation of change tracking.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;The Domain Model&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Here’s my domain model in the class designer:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://consultingblogs.emc.com/blogs/simonevans/image_310C0CDF.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://consultingblogs.emc.com/blogs/simonevans/image_thumb_499BAA2F.png" width="595" height="571" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While the differences in my model example are trivial (because the model is simple and I’m only implementing an EF repository), the domain model differs to the EDM in that address properties are named differently in this layer. This is purely to demonstrate how the mapper will work.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;The Repository&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Before showing the code for each part of the repository, here’s how the repository project is structured in solution explorer:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://consultingblogs.emc.com/blogs/simonevans/image_3752E36D.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://consultingblogs.emc.com/blogs/simonevans/image_thumb_6FFD8D7A.png" width="321" height="580" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Infrastructure assembly contains all the repository classes, separated by infrastructure concern (e.g. Entity Framework, WCF Data Services etc.). Notice that common classes such as the CommandRunner and RepositoryException are at the root of the namespace because they are not Entity Framework specific. The Installers folder contains all the Castle Windsor installers used for dependency injection.&lt;/p&gt;

&lt;p&gt;The Entity Framework folder contains all the EF specific repositories. Their associated Mappers and Commands are contained in in the corresponding sub folders.&lt;/p&gt;

&lt;p&gt;The repository interfaces are defined in the Domain project. Here’s the interface for the PersonRepository:&lt;/p&gt;

&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:0b251113-c1b1-40d6-be20-a2866b2d009b" class="wlWriterEditableSmartContent"&gt;&lt;pre style="width:591px;height:607px;background-color:White;overflow:auto;"&gt;&lt;div&gt;&lt;span style="color:#008080;"&gt; 1&lt;/span&gt; &lt;span style="color:#0000FF;"&gt;namespace&lt;/span&gt;&lt;span style="color:#000000;"&gt; EMC.Sample.Domain.Contracts.Repositories
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 2&lt;/span&gt; &lt;span style="color:#000000;"&gt;{
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 3&lt;/span&gt; &lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Collections.Generic;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 4&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 5&lt;/span&gt; &lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 6&lt;/span&gt; &lt;span style="color:#008000;"&gt;    &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; The repository for the &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;see cref=&amp;quot;Person &amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt; domain object.
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 7&lt;/span&gt; &lt;span style="color:#008000;"&gt;    &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 8&lt;/span&gt; &lt;span style="color:#808080;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;interface&lt;/span&gt;&lt;span style="color:#000000;"&gt; IPersonRepository
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 9&lt;/span&gt; &lt;span style="color:#000000;"&gt;    {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;10&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;11&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; Gets a person, including all child objects and collections.
&lt;/span&gt;&lt;span style="color:#008080;"&gt;12&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;13&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;param name=&amp;quot;id&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;The person id.&lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;14&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;15&lt;/span&gt; &lt;span style="color:#808080;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;        Person Get(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; id);
&lt;/span&gt;&lt;span style="color:#008080;"&gt;16&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;17&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;18&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; Persists a person (add or update), including all child objects and collections.
&lt;/span&gt;&lt;span style="color:#008080;"&gt;19&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;20&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;param name=&amp;quot;person&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;The person to persist.&lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;21&lt;/span&gt; &lt;span style="color:#808080;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; Persist(Person person);
&lt;/span&gt;&lt;span style="color:#008080;"&gt;22&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;23&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;24&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; Gets a list of all people.
&lt;/span&gt;&lt;span style="color:#008080;"&gt;25&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;26&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;27&lt;/span&gt; &lt;span style="color:#808080;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;        List&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Person&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; All();
&lt;/span&gt;&lt;span style="color:#008080;"&gt;28&lt;/span&gt; &lt;span style="color:#000000;"&gt;    }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;29&lt;/span&gt; &lt;span style="color:#000000;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This interface defines the repository has three interactions: Get, Persist and All, each working with one, or a collection of Person domain objects.&lt;/p&gt;

&lt;p&gt;Now lets look at the PersonRepository implementation:&lt;/p&gt;

&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:5b168b01-c807-4a63-ac84-1f3c59b64a4f" class="wlWriterEditableSmartContent"&gt;&lt;pre style="width:588px;height:657px;background-color:White;overflow:auto;"&gt;&lt;div&gt;&lt;span style="color:#008080;"&gt; 1&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 2&lt;/span&gt; &lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;namespace&lt;/span&gt;&lt;span style="color:#000000;"&gt; EMC.Sample.Infrastructure.EntityFramework
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 3&lt;/span&gt; &lt;span style="color:#000000;"&gt;{
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 4&lt;/span&gt; &lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Collections.Generic;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 5&lt;/span&gt; &lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; EMC.Sample.Domain.Contracts.Repositories;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 6&lt;/span&gt; &lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; EMC.Sample.Infrastructure.EntityFramework.Commands;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 7&lt;/span&gt; &lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; EMC.Sample.Data.Entity;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 8&lt;/span&gt; &lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; EMC.Sample.Framework.Mapper;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 9&lt;/span&gt; &lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; Entity &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; EMC.Sample.Data.Entity;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;10&lt;/span&gt; &lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; Person &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; EMC.Sample.Domain.Person;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;11&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;12&lt;/span&gt; &lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;13&lt;/span&gt; &lt;span style="color:#008000;"&gt;    &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; The entity framework implementation of the person repository interface.
&lt;/span&gt;&lt;span style="color:#008080;"&gt;14&lt;/span&gt; &lt;span style="color:#008000;"&gt;    &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;15&lt;/span&gt; &lt;span style="color:#808080;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; PersonRepository : IPersonRepository
&lt;/span&gt;&lt;span style="color:#008080;"&gt;16&lt;/span&gt; &lt;span style="color:#000000;"&gt;    {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;17&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;private&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;readonly&lt;/span&gt;&lt;span style="color:#000000;"&gt; IPersonCommands commands;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;18&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;private&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;readonly&lt;/span&gt;&lt;span style="color:#000000;"&gt; IEntityMapper mapper;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;19&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;private&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;readonly&lt;/span&gt;&lt;span style="color:#000000;"&gt; ICommandRunner runner;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;20&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;21&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;22&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; Initializes a new instance of the &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;see cref=&amp;quot;AddressRepository&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt; class.
&lt;/span&gt;&lt;span style="color:#008080;"&gt;23&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;24&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;param name=&amp;quot;mapper&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;The mapper used by methods in the repository to map between entities and domain objects.&lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;25&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;param name=&amp;quot;runner&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;The runner used by the repository to execute commands.&lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;26&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;param name=&amp;quot;commands&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;The commands that the repository is allowed to execute.&lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;27&lt;/span&gt; &lt;span style="color:#808080;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; PersonRepository(IEntityMapper mapper, ICommandRunner runner, IPersonCommands commands)
&lt;/span&gt;&lt;span style="color:#008080;"&gt;28&lt;/span&gt; &lt;span style="color:#000000;"&gt;        {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;29&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;this&lt;/span&gt;&lt;span style="color:#000000;"&gt;.commands &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; commands;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;30&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;this&lt;/span&gt;&lt;span style="color:#000000;"&gt;.mapper &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; mapper;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;31&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;this&lt;/span&gt;&lt;span style="color:#000000;"&gt;.runner &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; runner;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;32&lt;/span&gt; &lt;span style="color:#000000;"&gt;        }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;33&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;34&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; Person Get(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; id)
&lt;/span&gt;&lt;span style="color:#008080;"&gt;35&lt;/span&gt; &lt;span style="color:#000000;"&gt;        {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;36&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; (var context &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; ModelContext())
&lt;/span&gt;&lt;span style="color:#008080;"&gt;37&lt;/span&gt; &lt;span style="color:#000000;"&gt;            {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;38&lt;/span&gt; &lt;span style="color:#000000;"&gt;                Entity.Person personEntity &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;null&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;39&lt;/span&gt; &lt;span style="color:#000000;"&gt;                runner.Do(() &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; personEntity &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; commands.GetPersonById(id, context));
&lt;/span&gt;&lt;span style="color:#008080;"&gt;40&lt;/span&gt; &lt;span style="color:#000000;"&gt;                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; mapper.Map&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Person&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;(personEntity);
&lt;/span&gt;&lt;span style="color:#008080;"&gt;41&lt;/span&gt; &lt;span style="color:#000000;"&gt;            }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;42&lt;/span&gt; &lt;span style="color:#000000;"&gt;        }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;43&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;44&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; Persist(Person person)
&lt;/span&gt;&lt;span style="color:#008080;"&gt;45&lt;/span&gt; &lt;span style="color:#000000;"&gt;        {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;46&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; (var context &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; ModelContext())
&lt;/span&gt;&lt;span style="color:#008080;"&gt;47&lt;/span&gt; &lt;span style="color:#000000;"&gt;            {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;48&lt;/span&gt; &lt;span style="color:#000000;"&gt;                var personEntity &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; mapper.Map&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Entity.Person&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;(person);
&lt;/span&gt;&lt;span style="color:#008080;"&gt;49&lt;/span&gt; &lt;span style="color:#000000;"&gt;                var addresses &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; List&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Address&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;(personEntity.Addresses);
&lt;/span&gt;&lt;span style="color:#008080;"&gt;50&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;51&lt;/span&gt; &lt;span style="color:#000000;"&gt;                personEntity.Addresses.Clear();
&lt;/span&gt;&lt;span style="color:#008080;"&gt;52&lt;/span&gt; &lt;span style="color:#000000;"&gt;                runner.Do(() &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; commands.PersistPerson(personEntity, context));
&lt;/span&gt;&lt;span style="color:#008080;"&gt;53&lt;/span&gt; &lt;span style="color:#000000;"&gt;                addresses.ForEach(addressEntity &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; addressEntity.PersonId &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; personEntity.Id);
&lt;/span&gt;&lt;span style="color:#008080;"&gt;54&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;55&lt;/span&gt; &lt;span style="color:#000000;"&gt;                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;foreach&lt;/span&gt;&lt;span style="color:#000000;"&gt; (var addressEntity &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;in&lt;/span&gt;&lt;span style="color:#000000;"&gt; addresses)
&lt;/span&gt;&lt;span style="color:#008080;"&gt;56&lt;/span&gt; &lt;span style="color:#000000;"&gt;                {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;57&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    runner.ThenWithCompensation(() &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; commands.PersistAddress(addressEntity, context), onException &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;58&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;59&lt;/span&gt; &lt;span style="color:#000000;"&gt;                        runner.Compensate(() &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; commands.DeletePerson(personEntity, context));
&lt;/span&gt;&lt;span style="color:#008080;"&gt;60&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    });
&lt;/span&gt;&lt;span style="color:#008080;"&gt;61&lt;/span&gt; &lt;span style="color:#000000;"&gt;                }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;62&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;63&lt;/span&gt; &lt;span style="color:#000000;"&gt;                mapper.Map&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Person&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;(person, personEntity);
&lt;/span&gt;&lt;span style="color:#008080;"&gt;64&lt;/span&gt; &lt;span style="color:#000000;"&gt;            }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;65&lt;/span&gt; &lt;span style="color:#000000;"&gt;        }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;66&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;67&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; List&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Person&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; All()
&lt;/span&gt;&lt;span style="color:#008080;"&gt;68&lt;/span&gt; &lt;span style="color:#000000;"&gt;        {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;69&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; (var context &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; ModelContext())
&lt;/span&gt;&lt;span style="color:#008080;"&gt;70&lt;/span&gt; &lt;span style="color:#000000;"&gt;            {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;71&lt;/span&gt; &lt;span style="color:#000000;"&gt;                var peopleEntities &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; List&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Entity.Person&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;();
&lt;/span&gt;&lt;span style="color:#008080;"&gt;72&lt;/span&gt; &lt;span style="color:#000000;"&gt;                runner.Do(() &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; peopleEntities &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; commands.GetAllPeople(context));
&lt;/span&gt;&lt;span style="color:#008080;"&gt;73&lt;/span&gt; &lt;span style="color:#000000;"&gt;                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; mapper.Map&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;List&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Person&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;(peopleEntities);
&lt;/span&gt;&lt;span style="color:#008080;"&gt;74&lt;/span&gt; &lt;span style="color:#000000;"&gt;            }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;75&lt;/span&gt; &lt;span style="color:#000000;"&gt;        }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;76&lt;/span&gt; &lt;span style="color:#000000;"&gt;    }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;77&lt;/span&gt; &lt;span style="color:#000000;"&gt;}
&lt;/span&gt;&lt;span style="color:#008080;"&gt;78&lt;/span&gt; &lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;First thing to note is that the repository uses dependency injection to provide instances of the mapper, the commands and the command runner.&lt;/p&gt;

&lt;p&gt;Look at the simple Get method:&lt;/p&gt;

&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:aa5dfd57-a64b-45b5-ba4c-c567e54dd4a8" class="wlWriterEditableSmartContent"&gt;&lt;pre style="width:584px;height:214px;background-color:White;overflow:auto;"&gt;&lt;div&gt;&lt;span style="color:#008080;"&gt;1&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; Person Get(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; id)
&lt;/span&gt;&lt;span style="color:#008080;"&gt;2&lt;/span&gt; &lt;span style="color:#000000;"&gt;        {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;3&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; (var context &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; ModelContext())
&lt;/span&gt;&lt;span style="color:#008080;"&gt;4&lt;/span&gt; &lt;span style="color:#000000;"&gt;            {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;5&lt;/span&gt; &lt;span style="color:#000000;"&gt;                Entity.Person personEntity &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;null&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;6&lt;/span&gt; &lt;span style="color:#000000;"&gt;                runner.Do(() &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; personEntity &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; commands.GetPersonById(id, context));
&lt;/span&gt;&lt;span style="color:#008080;"&gt;7&lt;/span&gt; &lt;span style="color:#000000;"&gt;                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; mapper.Map&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Person&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;(personEntity);
&lt;/span&gt;&lt;span style="color:#008080;"&gt;8&lt;/span&gt; &lt;span style="color:#000000;"&gt;            }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;9&lt;/span&gt; &lt;span style="color:#000000;"&gt;        }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The core of this method uses the runner to execute a command (GetPersonById), and then uses the mapper (an AutoMapper profile) to map the EF entity (personEntity) to the Person domain object. Note that the runner is handling exceptions from EF and logging. More on that later.&lt;/p&gt;

&lt;p&gt;Now lets look at the Persist method (add or update):&lt;/p&gt;

&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:b2870b5a-34cd-4562-8683-0c361c76d996" class="wlWriterEditableSmartContent"&gt;&lt;pre style="width:581px;height:500px;background-color:White;overflow:auto;"&gt;&lt;div&gt;&lt;span style="color:#008080;"&gt; 1&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; Persist(Person person)
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 2&lt;/span&gt; &lt;span style="color:#000000;"&gt;        {
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 3&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; (var context &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; ModelContext())
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 4&lt;/span&gt; &lt;span style="color:#000000;"&gt;            {
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 5&lt;/span&gt; &lt;span style="color:#000000;"&gt;                var personEntity &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; mapper.Map&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Entity.Person&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;(person);
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 6&lt;/span&gt; &lt;span style="color:#000000;"&gt;                var addresses &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; List&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Address&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;(personEntity.Addresses);
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 7&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 8&lt;/span&gt; &lt;span style="color:#000000;"&gt;                personEntity.Addresses.Clear();
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 9&lt;/span&gt; &lt;span style="color:#000000;"&gt;                runner.Do(() &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; commands.PersistPerson(personEntity, context));
&lt;/span&gt;&lt;span style="color:#008080;"&gt;10&lt;/span&gt; &lt;span style="color:#000000;"&gt;                addresses.ForEach(addressEntity &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; addressEntity.PersonId &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; personEntity.Id);
&lt;/span&gt;&lt;span style="color:#008080;"&gt;11&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;12&lt;/span&gt; &lt;span style="color:#000000;"&gt;                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;foreach&lt;/span&gt;&lt;span style="color:#000000;"&gt; (var addressEntity &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;in&lt;/span&gt;&lt;span style="color:#000000;"&gt; addresses)
&lt;/span&gt;&lt;span style="color:#008080;"&gt;13&lt;/span&gt; &lt;span style="color:#000000;"&gt;                {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;14&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    runner.ThenWithCompensation(() &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; commands.PersistAddress(addressEntity, context), onException &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;15&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;16&lt;/span&gt; &lt;span style="color:#000000;"&gt;                        runner.Compensate(() &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; commands.DeletePerson(personEntity, context));
&lt;/span&gt;&lt;span style="color:#008080;"&gt;17&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    });
&lt;/span&gt;&lt;span style="color:#008080;"&gt;18&lt;/span&gt; &lt;span style="color:#000000;"&gt;                }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;19&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;20&lt;/span&gt; &lt;span style="color:#000000;"&gt;                mapper.Map&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Person&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;(person, personEntity);
&lt;/span&gt;&lt;span style="color:#008080;"&gt;21&lt;/span&gt; &lt;span style="color:#000000;"&gt;            }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;22&lt;/span&gt; &lt;span style="color:#000000;"&gt;        }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The first thing the persist method has to do is map between the inbound Person domain object and the EF personEntity. Earlier on in this post I described how the address entity is an aggregate root, and so has its own repository. However, the persist person method can also persist the associated addresses (along with the email addresses). In this method, the persistance of the email addresses is treated differently from the persistance of the addresses:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The personEntity is persisted with the associated email addresses by the PersistPerson command&lt;b&gt; in an ACID transaction&lt;/b&gt;. &lt;/li&gt;

  &lt;li&gt;The addresses are persisted by reusing the same PersistAddress command the AddressRepository uses &lt;b&gt;in their own ACID transactions&lt;/b&gt;. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because the addresses are persisted in their own transactions, this could leave the person entity in an inconsistent state if there is a failure in persisting an address. To counter this, the runner provides a delegate to execute compensation on exception (to delete the person entity).&lt;/p&gt;

&lt;p&gt;You may wonder why not just run everything in a single ACID transaction? On more complex models, executing everything in one transaction can effect scale due to mass database locks in SQL. While this may be a fairly trivial (and unlikely) example of compensation, it demonstrates a concept that normally makes data access code bloat, or worse still compensation is just ignored.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;The Mappers&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;The mappers used by the repository use AutoMapper profiles to limit the amount of code required to map between entities and domain objects. Here’s an example of the PersonMapperProfile: 
  &lt;br /&gt;&lt;/p&gt;

&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:ef567a55-e851-4617-93c0-6890164eaa59" class="wlWriterEditableSmartContent"&gt;&lt;pre style="width:579px;height:500px;background-color:White;overflow:auto;"&gt;&lt;div&gt;&lt;span style="color:#008080;"&gt; 1&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 2&lt;/span&gt; &lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;namespace&lt;/span&gt;&lt;span style="color:#000000;"&gt; EMC.Sample.Infrastructure.EntityFramework.Mappers
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 3&lt;/span&gt; &lt;span style="color:#000000;"&gt;{
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 4&lt;/span&gt; &lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; AutoMapper;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 5&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 6&lt;/span&gt; &lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; PersonMapperProfile : Profile
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 7&lt;/span&gt; &lt;span style="color:#000000;"&gt;    {
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 8&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;override&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; ProfileName
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 9&lt;/span&gt; &lt;span style="color:#000000;"&gt;        {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;10&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;get&lt;/span&gt;&lt;span style="color:#000000;"&gt; { &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;PersonMapperProfile&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;; }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;11&lt;/span&gt; &lt;span style="color:#000000;"&gt;        }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;12&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;13&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;protected&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;override&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; Configure()
&lt;/span&gt;&lt;span style="color:#008080;"&gt;14&lt;/span&gt; &lt;span style="color:#000000;"&gt;        {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;15&lt;/span&gt; &lt;span style="color:#000000;"&gt;            Mapper.CreateMap&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Data.Entity.Person, Domain.Person&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;()
&lt;/span&gt;&lt;span style="color:#008080;"&gt;16&lt;/span&gt; &lt;span style="color:#000000;"&gt;                .ForMember(to &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; to.Lastname, opt &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; opt.MapFrom(from &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; from.Surname));
&lt;/span&gt;&lt;span style="color:#008080;"&gt;17&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;18&lt;/span&gt; &lt;span style="color:#000000;"&gt;            Mapper.CreateMap&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Domain.Person, Data.Entity.Person&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;()
&lt;/span&gt;&lt;span style="color:#008080;"&gt;19&lt;/span&gt; &lt;span style="color:#000000;"&gt;                .ForMember(to &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; to.Surname, opt &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; opt.MapFrom(from &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; from.Lastname));
&lt;/span&gt;&lt;span style="color:#008080;"&gt;20&lt;/span&gt; &lt;span style="color:#000000;"&gt;        }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;21&lt;/span&gt; &lt;span style="color:#000000;"&gt;    }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;22&lt;/span&gt; &lt;span style="color:#000000;"&gt;}
&lt;/span&gt;&lt;span style="color:#008080;"&gt;23&lt;/span&gt; &lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This profile uses AutoMapper’s convention based mapping and tells AutoMapper what to do with the properties that fall outside of this convention (Surname to Lastname).&lt;/p&gt;

&lt;p&gt;&lt;b&gt;The Commands&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Lets look at the commands the Get and Persist repository calls use: &lt;/p&gt;

&lt;p&gt;
  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:60795866-603c-470d-b4a2-e4febd8db14c" class="wlWriterEditableSmartContent"&gt;&lt;pre style="width:578px;height:500px;background-color:White;overflow:auto;"&gt;&lt;div&gt;&lt;span style="color:#008080;"&gt; 1&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 2&lt;/span&gt; &lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;namespace&lt;/span&gt;&lt;span style="color:#000000;"&gt; EMC.Sample.Infrastructure.EntityFramework.Commands
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 3&lt;/span&gt; &lt;span style="color:#000000;"&gt;{
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 4&lt;/span&gt; &lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 5&lt;/span&gt; &lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Collections.Generic;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 6&lt;/span&gt; &lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Data;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 7&lt;/span&gt; &lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Linq;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 8&lt;/span&gt; &lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; EMC.Sample.Data.Entity;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 9&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;10&lt;/span&gt; &lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;11&lt;/span&gt; &lt;span style="color:#008000;"&gt;    &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; The Entity Framework implementation of all commands defined by each command interface implemented.
&lt;/span&gt;&lt;span style="color:#008080;"&gt;12&lt;/span&gt; &lt;span style="color:#008000;"&gt;    &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;13&lt;/span&gt; &lt;span style="color:#808080;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; Commands : IPersonCommands, IAddressCommands
&lt;/span&gt;&lt;span style="color:#008080;"&gt;14&lt;/span&gt; &lt;span style="color:#000000;"&gt;    {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;15&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;16&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; Gets a person by id.
&lt;/span&gt;&lt;span style="color:#008080;"&gt;17&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;18&lt;/span&gt; &lt;span style="color:#808080;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; Func&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt;, ModelContext, Person&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; GetPersonById
&lt;/span&gt;&lt;span style="color:#008080;"&gt;19&lt;/span&gt; &lt;span style="color:#000000;"&gt;        {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;20&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;get&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;21&lt;/span&gt; &lt;span style="color:#000000;"&gt;            {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;22&lt;/span&gt; &lt;span style="color:#000000;"&gt;                Func&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt;, ModelContext, Person&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; func &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; (personId, context) &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;23&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    context.People.Include(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Addresses&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;).Include(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;EmailAddresses&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;).FirstOrDefault(person &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; person.Id &lt;/span&gt;&lt;span style="color:#000000;"&gt;==&lt;/span&gt;&lt;span style="color:#000000;"&gt; personId);
&lt;/span&gt;&lt;span style="color:#008080;"&gt;24&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;25&lt;/span&gt; &lt;span style="color:#000000;"&gt;                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; func;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;26&lt;/span&gt; &lt;span style="color:#000000;"&gt;            }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;27&lt;/span&gt; &lt;span style="color:#000000;"&gt;        }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;28&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;29&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;30&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; Persists (inserts or updates) the person and any provided child objects in an ACID transaction.
&lt;/span&gt;&lt;span style="color:#008080;"&gt;31&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;32&lt;/span&gt; &lt;span style="color:#808080;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; Action&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Person, ModelContext&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; PersistPerson
&lt;/span&gt;&lt;span style="color:#008080;"&gt;33&lt;/span&gt; &lt;span style="color:#000000;"&gt;        {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;34&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;get&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;35&lt;/span&gt; &lt;span style="color:#000000;"&gt;            {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;36&lt;/span&gt; &lt;span style="color:#000000;"&gt;                Action&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Person, ModelContext&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; action &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; (person, context) &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;37&lt;/span&gt; &lt;span style="color:#000000;"&gt;                {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;38&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (person.Id &lt;/span&gt;&lt;span style="color:#000000;"&gt;==&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800080;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;)
&lt;/span&gt;&lt;span style="color:#008080;"&gt;39&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;40&lt;/span&gt; &lt;span style="color:#000000;"&gt;                        context.People.Add(person);
&lt;/span&gt;&lt;span style="color:#008080;"&gt;41&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;42&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;else&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;43&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;44&lt;/span&gt; &lt;span style="color:#000000;"&gt;                        context.People.Attach(person);
&lt;/span&gt;&lt;span style="color:#008080;"&gt;45&lt;/span&gt; &lt;span style="color:#000000;"&gt;                        context.Entry(person).State &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; EntityState.Modified;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;46&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;47&lt;/span&gt; &lt;span style="color:#000000;"&gt;                        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;foreach&lt;/span&gt;&lt;span style="color:#000000;"&gt; (var emailAddress &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;in&lt;/span&gt;&lt;span style="color:#000000;"&gt; person.EmailAddresses)
&lt;/span&gt;&lt;span style="color:#008080;"&gt;48&lt;/span&gt; &lt;span style="color:#000000;"&gt;                        {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;49&lt;/span&gt; &lt;span style="color:#000000;"&gt;                            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (emailAddress.Id &lt;/span&gt;&lt;span style="color:#000000;"&gt;==&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800080;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;)
&lt;/span&gt;&lt;span style="color:#008080;"&gt;50&lt;/span&gt; &lt;span style="color:#000000;"&gt;                            {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;51&lt;/span&gt; &lt;span style="color:#000000;"&gt;                                context.EmailAddresses.Add(emailAddress);
&lt;/span&gt;&lt;span style="color:#008080;"&gt;52&lt;/span&gt; &lt;span style="color:#000000;"&gt;                            }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;53&lt;/span&gt; &lt;span style="color:#000000;"&gt;                            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;else&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;54&lt;/span&gt; &lt;span style="color:#000000;"&gt;                            {
&lt;/span&gt;&lt;span style="color:#008080;"&gt;55&lt;/span&gt; &lt;span style="color:#000000;"&gt;                                context.EmailAddresses.Attach(emailAddress);
&lt;/span&gt;&lt;span style="color:#008080;"&gt;56&lt;/span&gt; &lt;span style="color:#000000;"&gt;                                context.Entry(emailAddress).State &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; EntityState.Modified;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;57&lt;/span&gt; &lt;span style="color:#000000;"&gt;                            }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;58&lt;/span&gt; &lt;span style="color:#000000;"&gt;                        }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;59&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;60&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;61&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    context.SaveChanges();
&lt;/span&gt;&lt;span style="color:#008080;"&gt;62&lt;/span&gt; &lt;span style="color:#000000;"&gt;                };
&lt;/span&gt;&lt;span style="color:#008080;"&gt;63&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;64&lt;/span&gt; &lt;span style="color:#000000;"&gt;                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; action;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;65&lt;/span&gt; &lt;span style="color:#000000;"&gt;            }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;66&lt;/span&gt; &lt;span style="color:#000000;"&gt;        }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;67&lt;/span&gt; &lt;span style="color:#000000;"&gt;    }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;68&lt;/span&gt; &lt;span style="color:#000000;"&gt;}
&lt;/span&gt;&lt;span style="color:#008080;"&gt;69&lt;/span&gt; &lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;

  &lt;br /&gt;As stated earlier, there is one single Commands class that implements multiple interfaces. These interfaces define what commands each repository can call.&lt;/p&gt;

&lt;p&gt;The interesting thing about this class is that each command is defined as a Func or Action property. The reason for this is so that the runner can inject exception handling and logging around each command. The repository shares object context between commands but the boundary of the transaction never flows beyond a single command. This promotes many small short transactions rather than one large transaction.&lt;/p&gt;

&lt;p&gt;Notice too how the persist command uses manual change tracking and not auto change tracking. The use of the CTP5 context.Entry(person).State tells entity framework what the state of the entity is. This manual control means we remove addition reads from our application which is important for stateless applications such as web sites and services.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;The Command Runner&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Finally, lets look at the runner code:&lt;/p&gt;

&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:13668a67-f840-4abd-aab6-651a38b800a6" class="wlWriterEditableSmartContent"&gt;&lt;pre style="width:559px;height:500px;background-color:White;overflow:auto;"&gt;&lt;div&gt;&lt;span style="color:#008080;"&gt;  1&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;  2&lt;/span&gt; &lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;namespace&lt;/span&gt;&lt;span style="color:#000000;"&gt; EMC.Sample.Infrastructure
&lt;/span&gt;&lt;span style="color:#008080;"&gt;  3&lt;/span&gt; &lt;span style="color:#000000;"&gt;{
&lt;/span&gt;&lt;span style="color:#008080;"&gt;  4&lt;/span&gt; &lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;  5&lt;/span&gt; &lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; EMC.Sample.Framework.Diagnostics;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;  6&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;  7&lt;/span&gt; &lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt;  8&lt;/span&gt; &lt;span style="color:#008000;"&gt;    &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; The implementation of the command runner interface.
&lt;/span&gt;&lt;span style="color:#008080;"&gt;  9&lt;/span&gt; &lt;span style="color:#008000;"&gt;    &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 10&lt;/span&gt; &lt;span style="color:#008000;"&gt;    &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;remarks&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;The command runner uses the ILog interface to log exceptions thrown by the entity framework.&lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/remarks&amp;gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 11&lt;/span&gt; &lt;span style="color:#808080;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; CommandRunner : ICommandRunner
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 12&lt;/span&gt; &lt;span style="color:#000000;"&gt;    {
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 13&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;private&lt;/span&gt;&lt;span style="color:#000000;"&gt; ILog log;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 14&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 15&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; CommandRunner(ILog log)
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 16&lt;/span&gt; &lt;span style="color:#000000;"&gt;        {
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 17&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;this&lt;/span&gt;&lt;span style="color:#000000;"&gt;.log &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; log;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 18&lt;/span&gt; &lt;span style="color:#000000;"&gt;        }
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 19&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 20&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 21&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; Executes the specified command.
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 22&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 23&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;param name=&amp;quot;command&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;The command.&lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 24&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 25&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; An instance of the command runner.
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 26&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 27&lt;/span&gt; &lt;span style="color:#808080;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; ICommandRunner Do(Action command)
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 28&lt;/span&gt; &lt;span style="color:#000000;"&gt;        {
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 29&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;this&lt;/span&gt;&lt;span style="color:#000000;"&gt;.DoWithCompensation(command, e &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; { });
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 30&lt;/span&gt; &lt;span style="color:#000000;"&gt;        }
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 31&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 32&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 33&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; Executes the specified command with compensation.
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 34&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 35&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;param name=&amp;quot;command&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;The command.&lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 36&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;param name=&amp;quot;compensation&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;The compensation.&lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 37&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 38&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; An instance of the command runner.
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 39&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 40&lt;/span&gt; &lt;span style="color:#808080;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; ICommandRunner DoWithCompensation(Action command, Action&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Exception&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; compensation)
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 41&lt;/span&gt; &lt;span style="color:#000000;"&gt;        {
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 42&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;try&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 43&lt;/span&gt; &lt;span style="color:#000000;"&gt;            {
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 44&lt;/span&gt; &lt;span style="color:#000000;"&gt;                command();
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 45&lt;/span&gt; &lt;span style="color:#000000;"&gt;            }
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 46&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;catch&lt;/span&gt;&lt;span style="color:#000000;"&gt; (Exception ex)
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 47&lt;/span&gt; &lt;span style="color:#000000;"&gt;            {
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 48&lt;/span&gt; &lt;span style="color:#000000;"&gt;                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (ex.InnerException &lt;/span&gt;&lt;span style="color:#000000;"&gt;!=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;null&lt;/span&gt;&lt;span style="color:#000000;"&gt;)
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 49&lt;/span&gt; &lt;span style="color:#000000;"&gt;                {
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 50&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    log.Write(LogMessageType.RepositoryException, ex.Message, ex.InnerException.Message);
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 51&lt;/span&gt; &lt;span style="color:#000000;"&gt;                }
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 52&lt;/span&gt; &lt;span style="color:#000000;"&gt;                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;else&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 53&lt;/span&gt; &lt;span style="color:#000000;"&gt;                {
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 54&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    log.Write(LogMessageType.RepositoryException, ex.Message, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt;.Empty);
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 55&lt;/span&gt; &lt;span style="color:#000000;"&gt;                }
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 56&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 57&lt;/span&gt; &lt;span style="color:#000000;"&gt;                compensation(ex);
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 58&lt;/span&gt; &lt;span style="color:#000000;"&gt;                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;throw&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; RepositoryException(ex.Message, ex);
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 59&lt;/span&gt; &lt;span style="color:#000000;"&gt;            }
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 60&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 61&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;this&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 62&lt;/span&gt; &lt;span style="color:#000000;"&gt;        }
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 63&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 64&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 65&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; Executes the specified command.
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 66&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 67&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;param name=&amp;quot;command&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;The command.&lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 68&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 69&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; An instance of the command runner.
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 70&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 71&lt;/span&gt; &lt;span style="color:#808080;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; ICommandRunner Then(Action command)
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 72&lt;/span&gt; &lt;span style="color:#000000;"&gt;        {
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 73&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;this&lt;/span&gt;&lt;span style="color:#000000;"&gt;.DoWithCompensation(command, e &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; { });
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 74&lt;/span&gt; &lt;span style="color:#000000;"&gt;        }
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 75&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 76&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 77&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; Executes the specified command with compensation.
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 78&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 79&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;param name=&amp;quot;command&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;The command.&lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 80&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;param name=&amp;quot;compensation&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;The compensation.&lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 81&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 82&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; An instance of the command runner.
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 83&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 84&lt;/span&gt; &lt;span style="color:#808080;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; ICommandRunner ThenWithCompensation(Action command, Action&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Exception&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; compensation)
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 85&lt;/span&gt; &lt;span style="color:#000000;"&gt;        {
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 86&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;this&lt;/span&gt;&lt;span style="color:#000000;"&gt;.DoWithCompensation(command, compensation);
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 87&lt;/span&gt; &lt;span style="color:#000000;"&gt;        }
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 88&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 89&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 90&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; Executes the specified command.
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 91&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 92&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;param name=&amp;quot;command&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;The command.&lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 93&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 94&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; An instance of the command runner.
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 95&lt;/span&gt; &lt;span style="color:#008000;"&gt;        &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 96&lt;/span&gt; &lt;span style="color:#808080;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; ICommandRunner Compensate(Action command)
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 97&lt;/span&gt; &lt;span style="color:#000000;"&gt;        {
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 98&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;this&lt;/span&gt;&lt;span style="color:#000000;"&gt;.Do(command);
&lt;/span&gt;&lt;span style="color:#008080;"&gt; 99&lt;/span&gt; &lt;span style="color:#000000;"&gt;        }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;100&lt;/span&gt; &lt;span style="color:#000000;"&gt;    }
&lt;/span&gt;&lt;span style="color:#008080;"&gt;101&lt;/span&gt; &lt;span style="color:#000000;"&gt;}
&lt;/span&gt;&lt;span style="color:#008080;"&gt;102&lt;/span&gt; &lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The majority of this class is syntactic sugar (such as the Then method). Note each method returns ICommandRunner, which provides a fluent API for executing commands.&lt;/p&gt;

&lt;p&gt;The meat of this class is the DoWithCompensation method which templates the command and compensation passed in with an exception block and logging.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Next time…&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;I will be posting similar examples of using the repository-mapper-command pattern with a WCF Data Service and Azure Table Storage in the future. Stay tuned.&lt;/p&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=18200" width="1" height="1"&gt;</description></item><item><title>Entity Framework 4 : Implementation Options</title><link>http://consultingblogs.emc.com/simonevans/archive/2011/01/31/entity-framework-4-implementation-options.aspx</link><pubDate>Mon, 31 Jan 2011 16:35:23 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:18186</guid><dc:creator>simon.evans</dc:creator><slash:comments>2</slash:comments><comments>http://consultingblogs.emc.com/simonevans/comments/18186.aspx</comments><wfw:commentRss>http://consultingblogs.emc.com/simonevans/commentrss.aspx?PostID=18186</wfw:commentRss><description>&lt;p&gt;The .NET 4 version of the Entity Framework (EF) brought several major improvements over the first version of the ORM; these features have since been extended further through the soon to be released add on &lt;a href="http://blogs.msdn.com/b/adonet/archive/2010/12/06/ef-feature-ctp5-released.aspx" target="_blank"&gt;EF Features CTP 5&lt;/a&gt;. Note for the rest of this post, when I refer to EF, I mean EF4 with the CTP 5 installed too.&lt;/p&gt;  &lt;p&gt;The new features in EF provide much greater choice of how you choose to work with the framework; version 1 of the Entity Framework (part of .NET 3.5 SP1) gave you exactly one way of working with it (database first), which grated on many people who preferred to work “object model first”.&lt;/p&gt;  &lt;p&gt;Working “object model first” means that you prefer to design your solution considering the object model before you consider the data model. This does not mean that you do not consider the data model at all; rather you choose to design this concern first. There are several reasons why you may choose to do this, but I think the most compelling reason is that the object model view of the world touches far more of your application than the data model does; indeed if you opt to work test driven, you will be wanting to work with the object model first so you can create your tests.&lt;/p&gt;  &lt;p&gt;In reality, working “object model first” in EF means one of two main options:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Working &lt;strong&gt;“Model First”&lt;/strong&gt; with the Entity Data Model (&lt;a href="http://msdn.microsoft.com/en-us/library/bb387122(v=VS.90).aspx" target="_blank"&gt;EDM&lt;/a&gt;) tooling in Visual Studio&lt;/li&gt;    &lt;li&gt;Working&lt;strong&gt; “Code First”&lt;/strong&gt; writing POCO domain objects in code (or using the class designer) and using the convention based API handle data mapping.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Both of these options provide a way of automatically generating the underlying SQL data model.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;“Model First” development using the Entity Framework&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Model First development in EF means working with the Entity Data Model (EDM). The EDM is a model abstraction concerned with mapping Entities (objects) to Data (relational stores). The EDM is an XML format consisting of three core sections: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;the conceptual model (CSDL) which models the entities, &lt;/li&gt;    &lt;li&gt;the structural model (SSDL) which models the data and &lt;/li&gt;    &lt;li&gt;the mapping model (MSL) with manages the impedance mismatch of the two. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The EDM has been a core part of EF from version one. Most people view the EDM through Visual Studio tooling, which looks like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://consultingblogs.emc.com/blogs/simonevans/EDM-Designer_4D843021.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="EDM Designer" border="0" alt="EDM Designer" src="http://consultingblogs.emc.com/blogs/simonevans/EDM-Designer_thumb_1EBE777F.png" width="822" height="572" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Working model first with the EDM provides benefits in three key benefits over code first:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;It enables developers to visualize the problem and focus on the whole model rather than individual aspects of it.&lt;/li&gt;    &lt;li&gt;It provides build time validation that your entities will work for all CRUD operations no matter how you navigate the object model (via &lt;a href="http://msdn.microsoft.com/en-us/library/bb387165.aspx" target="_blank"&gt;edmgen.exe&lt;/a&gt;).&lt;/li&gt;    &lt;li&gt;It provides a way of working effectively with data architects in a domain that they are expert in.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The complexity of the model in question will determine the value of working model first; the more complex the model, the more valuable a model first approach is.&lt;/p&gt;  &lt;p&gt;Code is generated from the model. Code generation happens through the Visual Studio tooling (&lt;a href="http://msdn.microsoft.com/en-us/library/bb387165.aspx" target="_blank"&gt;Edmgen.exe&lt;/a&gt; and T4 templates). In EF there are now three auto-generation options for implementing a model first approach:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Using the basic ObjectContext implementation to generate entities which inherit from the &lt;a href="http://msdn.microsoft.com/en-us/library/system.data.objects.dataclasses.entityobject.aspx" target="_blank"&gt;EntityObject&lt;/a&gt; class (like EF v1). &lt;/li&gt;    &lt;li&gt;Using &lt;a href="http://blogs.msdn.com/b/efdesign/archive/2009/03/24/self-tracking-entities-in-the-entity-framework.aspx" target="_blank"&gt;self tracking entities&lt;/a&gt;. It differs from option one in that the entities do not inherit from the EntityObject class and do not depend on the System.Data.Entity assembly (the generated ObjectContext still does). Thus self tracking entities can be used as currency between layers of an n-tier application. Like option one, the entities are automatically tracking by the object context.&lt;/li&gt;    &lt;li&gt;Using &lt;a href="http://blogs.microsoft.co.il/blogs/gilf/archive/2010/12/08/ef-feature-ctp5-walkthrough-for-the-new-dbcontext-t4-template.aspx" target="_blank"&gt;POCO entities&lt;/a&gt; (CTP 5 only). This option is similar to self tracking entities except that the entities are completely ignorant of change tracking.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Additionally you can switch off code generation and roll your own if you prefer. In this case the POCO entity properties must match the entities properties you model in the EDM (the CSDL section of the model).&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;“Code First” development using the Entity Framework&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Code first development (CTP 5 only) means that you write your entity objects as POCO classes and use a convention based approach to handling mapping to a data model. A detailed blog on how to do this can be found on the &lt;a href="http://blogs.msdn.com/b/adonet/archive/2010/12/14/ef-feature-ctp5-code-first-walkthrough.aspx" target="_blank"&gt;ADO.NET team blog&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Working code first has the following benefits over model first:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;More light weight approach with less artefacts.&lt;/li&gt;    &lt;li&gt;Suits developers who prefer to work with code rather than a visual abstraction.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Which approach is best for me?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I’ve spent a while trying to distil out of my head what the key factors are in making these decisions. I think ultimately, there are three key factors:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The type of application or service being built, such as a web application, service, thick client or RIA application.&lt;/li&gt;    &lt;li&gt;The number of data stores or services the application will consume.&lt;/li&gt;    &lt;li&gt;The complexity of the data store you are surfacing through EF.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The last of these three points is hardest to quantify, because complexity is subjective. The main point that makes a model core complex is shear number of entities and relationships. If you cant easily picture all your systems relationships in your head, then you will get value from a model.&lt;/p&gt;    &lt;p&gt;The diagram below illustrates the decision tree as to which approach I think best suits each option:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://consultingblogs.emc.com/blogs/simonevans/Entity-Framework-Options_1E52448A.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="Entity Framework Options" border="0" alt="Entity Framework Options" src="http://consultingblogs.emc.com/blogs/simonevans/Entity-Framework-Options_thumb_79C0B705.png" width="1558" height="472" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Here’s the key points from this diagram:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Value the EDM over code first in more complex modelling scenarios.&lt;/li&gt;    &lt;li&gt;With the exception of WCF Data Services, use manual change tracking against POCO entities in stateless applications (e.g. websites and services).&lt;/li&gt;    &lt;li&gt;Use self tracking entities with auto change tracking for simple thick client (stateful) applications.&lt;/li&gt;    &lt;li&gt;If you only have one data store, use your entities as Domain objects in your application or service.&lt;/li&gt;    &lt;li&gt;When you implement multiple stores implement&amp;#160; domain-to-entity model mapping within your repository where necessary. A good way to do this without introducing code bloat is using &lt;a href="http://automapper.codeplex.com/" target="_blank"&gt;AutoMapper&lt;/a&gt; profiles as described by &lt;a href="http://consultingblogs.emc.com/owainwragg/archive/2010/12/15/automapper-profiles.aspx" target="_blank"&gt;Owain Wragg’s blog here&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=18186" width="1" height="1"&gt;</description><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/.NET/default.aspx">.NET</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/ADO.NET/default.aspx">ADO.NET</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/ORM/default.aspx">ORM</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/Visual+Studio+2010/default.aspx">Visual Studio 2010</category></item><item><title>Liberating Identity using Windows Identity Foundation</title><link>http://consultingblogs.emc.com/simonevans/archive/2010/12/08/liberating-identity-using-windows-identity-foundation.aspx</link><pubDate>Wed, 08 Dec 2010 15:36:35 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:17986</guid><dc:creator>simon.evans</dc:creator><slash:comments>0</slash:comments><comments>http://consultingblogs.emc.com/simonevans/comments/17986.aspx</comments><wfw:commentRss>http://consultingblogs.emc.com/simonevans/commentrss.aspx?PostID=17986</wfw:commentRss><description>&lt;p&gt;Last night I presented to the &lt;a href="http://lcsug.eventbrite.com/" target="_blank"&gt;London Connected Systems User Group&lt;/a&gt; on the subject of Windows Identity Foundation (WIF).&lt;/p&gt;  &lt;p&gt;The LCSUG community is focussed around building and integrating services. One architectural concern that has been widely ignored in service oriented architecture is identity and access control. Web based identity protocols such as WS-Trust, OAuth WRAP and WS-Federation are of great importance to service and application design because they enable identity to be freed beyond the boundaries of an application or single enterprise and onto the web.&lt;/p&gt;  &lt;p&gt;The software demands of end users have changed in recent years; people expect access to information anywhere from any device all the time. For most enterprises, this demand will mean provisioning internet facing applications and services in a public cloud, while key tier 1 or line of business applications will remain under close supervision on premise or in a private cloud. This is reality of “hybrid cloud” scenarios.&lt;/p&gt;  &lt;p&gt;To deliver cloud enterprise architecture you need one key ingredient : HTTP. Identity that flows over HTTP(S) enables access control to operate from device to service and beyond in a way that it seamless and invisible to end users. This web single sign on capability is also becoming a key differentiator in a users experience of an application.&lt;/p&gt;  &lt;p&gt;The slide deck I gave last night can be viewed below:&lt;/p&gt;  &lt;div style="width:425px;" id="__ss_6077332"&gt;&lt;object id="__sse6077332" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=lcsug-101208073847-phpapp01&amp;amp;stripped_title=liberating-identity-using-windows-identity-foundation&amp;amp;userName=simonrevans" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;param name="allowScriptAccess" value="always" /&gt;&lt;embed name="__sse6077332" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=lcsug-101208073847-phpapp01&amp;amp;stripped_title=liberating-identity-using-windows-identity-foundation&amp;amp;userName=simonrevans" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;  &lt;p&gt;Over the next few weeks I will be providing detailed examples of using WIF with ASP.NET MVC, WCF and WCF Data Services.&lt;/p&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=17986" width="1" height="1"&gt;</description><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/Microsoft/default.aspx">Microsoft</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/.NET/default.aspx">.NET</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/WCF/default.aspx">WCF</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/SOA/default.aspx">SOA</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/Windows+Azure/default.aspx">Windows Azure</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/Identity/default.aspx">Identity</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/Windows+Identity+Foundation/default.aspx">Windows Identity Foundation</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/WIF/default.aspx">WIF</category></item><item><title>Common Windows Identity Foundation WS-Federation Exceptions Explained</title><link>http://consultingblogs.emc.com/simonevans/archive/2010/11/19/common-windows-identity-foundation-ws-federation-exceptions-explained.aspx</link><pubDate>Fri, 19 Nov 2010 14:51:43 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:17932</guid><dc:creator>simon.evans</dc:creator><slash:comments>2</slash:comments><comments>http://consultingblogs.emc.com/simonevans/comments/17932.aspx</comments><wfw:commentRss>http://consultingblogs.emc.com/simonevans/commentrss.aspx?PostID=17932</wfw:commentRss><description>&lt;h1&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;/h1&gt;  &lt;p&gt;Windows Identity Foundation (WIF) is a hugely important part of the .NET Framework, enabling you to architect and develop relying parties (RP) and security token servers (STS) that use claims based identity models. For all of this goodness, WIF is surprisingly undocumented on MSDN for a release product (at the time of writing at least), and when developing against it, it won’t be long before you come across “ID” exceptions which have little or no explanation. &lt;/p&gt;  &lt;p&gt;Having spent many hours of my life trawling through forums trying to understand the issues, I’ve decided to blog a list of every exception I have seen when using WIF to create a relying party ASP.NET website that uses WS-Federation to authenticate with a security token server. This is sometimes called “passive” authentication, where the browser is acting as a thin client “middle man” in the federation process between the RP and the STS.&lt;/p&gt;  &lt;p&gt;Note that this blog is not a guide to developing with WIF, WS-Federation or its use with ASP.NET; I’ll assume you already know how the pieces fit together. If you want some good resources on how to get developing with WIF, I suggest you look here:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/vbertocci/" target="_blank"&gt;Vittorio Bertocci’s blog&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.leastprivilege.com/"&gt;http://www.leastprivilege.com/&lt;/a&gt; blog &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.amazon.com/Programming-Windows-Identity-Foundation-Dev/dp/0735627185/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1290178278&amp;amp;sr=1-1" target="_blank"&gt;Buy the Programming Windows Identity Foundation book&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ff423674.aspx" target="_blank"&gt;Download the Patterns and Practices guide&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The following table describes several common Windows Identity Foundation exceptions associated with using WIF to build a relying party using WS-Federation:&lt;/p&gt;  &lt;table border="1" cellspacing="0" cellpadding="2" width="666"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;&lt;strong&gt;WIF Exception&lt;/strong&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;&lt;strong&gt;Error Message&lt;/strong&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;&lt;strong&gt;What does that mean?&lt;/strong&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p align="left"&gt;ID1025&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="left"&gt;Cannot find a unique certificate that matches the criteria.&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="left"&gt;The relying party is unable to read the security token which has been encrypted at a message level by the issuing STS. In order for the relying party to decrypt the token, it needs access to the x.509 certificate used to encrypt the token. This certificate is referenced in the relying party’s WIF configuration under the &amp;lt;serviceCertificate&amp;gt; element. This exception is stating that there is an issue identifying a unique certificate that matches the configuration.&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p align="left"&gt;ID4036&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="left"&gt;The key needed to decrypt the encrypted security token could not be resolved from the following security key identifier&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="left"&gt;This exception follows on from the ID1025 exception above. We are still trying to decrypt an encrypted security token using the information contained in the &amp;lt;serviceCertificate&amp;gt; element. This time however, WIF&amp;#160; has managed to uniquely identify the certificate, but it cannot access the certificates private key to execute decryption. Not being able to access the certificate’s private key may be either because the certificate is missing a private key, or because the service account the relying party website is using does not have permissions to read the private key.&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p align="left"&gt;ID4175&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="left"&gt;The issuer of the security token was not recognized by the IssuerNameRegistry. To accept security tokens from this issuer, configure the IssuerNameRegistry to return a valid name for this issuer.&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="left"&gt;Security tokens are signed by the issuer (the IP-STS). This issuer is validated by the relying party so that the RP can be sure the tokens have been issued from a trusted source. The relying party’s WIF configuration contains an &amp;lt;issuerNameRegistry&amp;gt; element where the settings for the issuer’s signature are stored. This exception means that the configuration contained under the issuer name registry does not match the signature of the security token.&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p align="left"&gt;ID4291&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="left"&gt;The security token 'Microsoft.IdentityModel.Tokens. SessionSecurityToken' is not scoped to the current endpoint.&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="left"&gt;Session security tokens are scoped to work only for a single relying party, based on the realm and audience configuration in WIF. This is demonstrated by the path of cookies created by the cookie handler. If you attempt to use this cookie for another RP of sub application of the RP, you will see this exception.&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p align="left"&gt;ID1073&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="left"&gt;A CryptographicException occurred when attempting to decrypt the cookie using the ProtectedData API&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="left"&gt;The cookie the message refers to is the session security token stored as a series of cookies named FedAuth1 to FedAuthX (based on the size of the SessionSecurityToken). The Session Authentication Module (SAM) is responsible for managing the reading and writing of the the session security token information between page requests, using a cookie handler to physically read and write the cookies in the request and response stream. This exception states that the encrypted session security token could not be decrypted by the SAM. The encryption method stated here is DPAPI.&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p align="left"&gt;ID1074&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="left"&gt;A CryptographicException occurred when attempting to encrypt the cookie using the ProtectedData API&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="left"&gt;The cookie the message refers to is the session security token stored as a series of cookies named FedAuth1 to FedAuthX (based on the size of the SessionSecurityToken). The Session Authentication Module (SAM) is responsible for managing the reading and writing of the the session security token information between page requests, using a cookie handler to physically read and write the cookies in the request and response stream. This exception states that the session security token could not be encrypted by the SAM. The encryption method stated here is DPAPI.&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;h3&gt;How do I fix ID1025?&lt;/h3&gt;  &lt;p&gt;There are several ways to identify a certificate (e.g. via a certificate’s thumbprint or subject name). Make sure the certificate is complete and installed correctly and the identifier is correct. For example&lt;/p&gt;  &lt;p align="left"&gt;&lt;font face="Courier New"&gt;&amp;lt;certificateReference x509FindType=&amp;quot;FindBySubjectName&amp;quot; findValue=&amp;quot;mysubjectname&amp;quot; storeLocation=&amp;quot;LocalMachine&amp;quot; storeName=&amp;quot;My&amp;quot; /&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This configuration references the certificate by subject name (called mysubjectname) in a store on the same machine. Note that storeName “My” actually refers to certificates stored under Personal certificates when viewed the certificates MMC snap in.&lt;/p&gt;  &lt;p&gt;Be careful when using FindByThumbprint. I have seen issues with this because the thumbprint value has to be correct in hex and configuration file encoding can screw this up and cause much pain during configuration management.&lt;/p&gt;  &lt;h3&gt;How do I fix ID4036?&lt;/h3&gt;  &lt;p align="left"&gt;Firstly, ensure that your certificate is complete with all the required properties for use with WIF (see below).&lt;/p&gt;  &lt;p align="left"&gt;Assuming that is the case, check which user account your web site is running under in IIS by:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;     &lt;div align="left"&gt;Looking at the sites basic settings and checking which app pool the site is using.&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="left"&gt;Looking at the named app pool and checking the identity by selecting advanced settings of the app pool.&lt;/div&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;p align="left"&gt;Next, open up MMC and add the certificate snap in and manage certificates for the computer account.&lt;/p&gt;  &lt;p align="left"&gt;Navigate to Personal &amp;gt; Certificates. Select the appropriate certificate referenced by WIF, right click All Tasks &amp;gt; Manage Private Keys. Ensure that the identity account used by the app pool has read access to the private key.&lt;/p&gt;  &lt;h3 align="left"&gt;How do I fix ID4291?&lt;/h3&gt;  &lt;p align="left"&gt;Check the path of the chunked cookie (using development tools in Firefox) and ensure they match your configuration as expected. Check if your application contains any sub web applications. If needed, you may need to force the cookie path by setting the &amp;lt;cookieHandler path=&amp;quot;custompath&amp;quot; /&amp;gt; configuration attribute.&lt;/p&gt;  &lt;h3 align="left"&gt;How do I fix ID1073?&lt;/h3&gt;  &lt;p align="left"&gt;Using DPAPI requires the app pool load user profile setting to be turned on for the app pool in IIS. To do this, go to the app pool &amp;gt; advanced settings and set Load User Profile to true.&lt;/p&gt;  &lt;p align="left"&gt;This will now work fine for the default ApplicationPoolIdentity account, but in production systems running a custom windows account (on 64bit), you will still get the same exception when the app pool recycles (I don’t know why).&lt;/p&gt;  &lt;p align="left"&gt;I solved this by switching the token format from DPAPI to an RSA cryptographic algorithm using the following&amp;#160; WIF event handler in the global.asax:&lt;/p&gt;  &lt;p&gt;protected void OnServiceConfigurationCreated(object sender, ServiceConfigurationCreatedEventArgs e)   &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; //     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; // Use the &amp;lt;serviceCertificate&amp;gt; to protect the cookies that are     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; // sent to the client.     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; //     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; List&amp;lt;CookieTransform&amp;gt; sessionTransforms =    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; new List&amp;lt;CookieTransform&amp;gt;(new CookieTransform[] {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; new DeflateCookieTransform(),     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; new RsaEncryptionCookieTransform(e.ServiceConfiguration.ServiceCertificate),     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; new RsaSignatureCookieTransform(e.ServiceConfiguration.ServiceCertificate) });&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; SessionSecurityTokenHandler sessionHandler = new   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SessionSecurityTokenHandler(sessionTransforms.AsReadOnly());&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; e.ServiceConfiguration.SecurityTokenHandlers.AddOrReplace(sessionHandler);   &lt;br /&gt;}     &lt;br /&gt;&lt;/p&gt;  &lt;p align="left"&gt;This code has the added benefit of working in a web farm without all nodes in your farm sharing the same machine key in configuration, which is much nicer (and what I needed).&lt;/p&gt;  &lt;h3&gt;How do I fix ID1074?&lt;/h3&gt;  &lt;p align="left"&gt;I have only seen one cause of this failure. Image your relying party is accessed at:&lt;/p&gt;  &lt;p align="left"&gt;&lt;a href="https://mysite.com/myapplication/"&gt;https://mysite.com/myapplication/&lt;/a&gt;&lt;/p&gt;  &lt;p align="left"&gt;This is your audience URI used on the security token issued from the STS.&lt;/p&gt;  &lt;p align="left"&gt;Now if your user access the relying party by:&lt;/p&gt;  &lt;p align="left"&gt;&lt;a href="https://mysite.com/myapplication"&gt;https://mysite.com/myapplication&lt;/a&gt;&lt;/p&gt;  &lt;p align="left"&gt;the lack of closing slash on the end of the URI gives this exception thrown by the FAM. This is surely a bug in WIF.&lt;/p&gt;  &lt;p align="left"&gt;The workaround for me was to switch off passive redirect in the FAM configuration:&lt;/p&gt;  &lt;p align="left"&gt;&lt;font face="Courier New"&gt;&amp;lt;federatedAuthentication&amp;gt;     &lt;br /&gt;&amp;#160; &amp;lt;wsFederation &lt;font color="#ff0000"&gt;&lt;strong&gt;passiveRedirectEnabled=&amp;quot;false&amp;quot;&lt;/strong&gt;&lt;/font&gt; issuer=&amp;quot;&lt;/font&gt;&lt;a href="https://close-brothers.dev/closests/identity/issue&amp;quot;"&gt;&lt;font face="Courier New"&gt;https://close-brothers.dev/closests/identity/issue&amp;quot;&lt;/font&gt;&lt;/a&gt;&lt;font face="Courier New"&gt; realm=&amp;quot;&lt;/font&gt;&lt;a href="https://close-brothers.dev/closeasset/federation&amp;quot;"&gt;&lt;font face="Courier New"&gt;https://close-brothers.dev/closeasset/federation&amp;quot;&lt;/font&gt;&lt;/a&gt;&lt;font face="Courier New"&gt; homeRealm=&amp;quot;&lt;/font&gt;&lt;a href="https://close-brothers.dev/closests/identity/issue&amp;quot;"&gt;&lt;font face="Courier New"&gt;https://close-brothers.dev/closests/identity/issue&amp;quot;&lt;/font&gt;&lt;/a&gt;&lt;font face="Courier New"&gt; requireHttps=&amp;quot;true&amp;quot; /&amp;gt;     &lt;br /&gt;&amp;#160; &amp;lt;cookieHandler requireSsl=&amp;quot;true&amp;quot; /&amp;gt;      &lt;br /&gt;&amp;lt;/federatedAuthentication&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;font face="Courier New"&gt;&lt;font face="Tahoma"&gt;and then write code to handle the redirect myself. Again, this workaround was something I think I would have needed regardless, because my site uses ASP.NET MVC and I want the routing engine to handle all requests and provide plumbing for home realm discovery.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;  &lt;h3&gt;WIF and x.509 certificate creation in the real world&lt;/h3&gt;  &lt;p&gt;When you develop with WIF, you are given a handy little tool called FedUtil.exe. It does a bunch of things, like change your application configuration, and generating self signed certificates under the covers.&lt;/p&gt;  &lt;p&gt;As useful as this is for development, when it comes to deployment on production environments, you will want to have all the certificates signed with a certificate authority, and you will want control of certificate generation using MakeCert.&lt;/p&gt;  &lt;p&gt;The lack of WIF documentation here is very tiring and is from my experience the reason for half of the exceptions I mention above. With the help of two platform architects (Thanks to James Dawson and Barry Feist) we figured out what our makecert commands need to be:&lt;/p&gt;  &lt;p align="left"&gt;&lt;font face="Courier New"&gt;REM Root Certificate Authority     &lt;br /&gt;makecert.exe -pe -n &amp;quot;CN=My Root CA,O=MyOrg, OU=Dev, L=London, C=GB&amp;quot; -ss my -sr LocalMachine -sky exchange -a sha1 -r &amp;quot;MyRootCA.cer&amp;quot;&lt;/font&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;font face="Courier New"&gt;REM SSL Cert     &lt;br /&gt;makecert.exe -pe -n &amp;quot;CN=ssl.dev,O=MyOrg, OU=Dev, L=London, C=GB&amp;quot; -ss my -sr LocalMachine -a sha1 -sky exchange -eku 1.3.6.1.5.5.7.3.1,1.3.6.1.5.5.7.3.2 -in &amp;quot;My Root CA&amp;quot; -is My -ir LocalMachine -sp &amp;quot;Microsoft RSA SChannel Cryptographic Provider&amp;quot; -sy 12 &amp;quot;MyRootCA.cer&amp;quot;&lt;/font&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;font face="Courier New"&gt;REM STS Cert     &lt;br /&gt;makecert.exe -pe -n &amp;quot;CN=STS.Web,O=MyOrg, OU=Dev, L=London, C=GB&amp;quot; -ss my -sr LocalMachine -a sha1 -sky exchange -eku 1.3.6.1.5.5.7.3.1 -in &amp;quot;My Root CA&amp;quot; -is My -ir LocalMachine -sp &amp;quot;Microsoft RSA SChannel Cryptographic Provider&amp;quot; -sy 12 &amp;quot;MyRootCA.cer&amp;quot;&lt;/font&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;font face="Courier New"&gt;REM Relying Party Cert     &lt;br /&gt;REM makecert.exe -pe -n &amp;quot;CN=RelyingParty.Web,O=MyOrg, OU=Dev, L=London, C=GB&amp;quot; -ss my -sr LocalMachine -a sha1 -sky exchange -eku 1.3.6.1.5.5.7.3.2 -in &amp;quot;My Root CA&amp;quot; -is My -ir LocalMachine -sp &amp;quot;Microsoft RSA SChannel Cryptographic Provider&amp;quot; -sy 12 &amp;quot;MyRootCA.cer&amp;quot;      &lt;br /&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Here we are creating four certificates. The first is the root CA. The second is a certificate we using for SSL between the relying party and the STS. The third is a certificate used by the STS to sign tokens. The final certificate is used to encrypt the security token and decrypt the token by the relying party.&lt;/p&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=17932" width="1" height="1"&gt;</description><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/ASP.NET+MVC/default.aspx">ASP.NET MVC</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/Identity/default.aspx">Identity</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/Windows+Identity+Foundation/default.aspx">Windows Identity Foundation</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/WIF/default.aspx">WIF</category></item><item><title>Consuming data from Windows Azure Table Storage using the Repository-Mapper-Command pattern</title><link>http://consultingblogs.emc.com/simonevans/archive/2010/08/18/consuming-data-from-windows-azure-table-storage-using-the-repository-mapper-command-pattern.aspx</link><pubDate>Wed, 18 Aug 2010 11:27:17 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:17575</guid><dc:creator>simon.evans</dc:creator><slash:comments>1</slash:comments><comments>http://consultingblogs.emc.com/simonevans/comments/17575.aspx</comments><wfw:commentRss>http://consultingblogs.emc.com/simonevans/commentrss.aspx?PostID=17575</wfw:commentRss><description>&lt;p&gt;Back in May I &lt;a href="http://consultingblogs.emc.com/simonevans/archive/2010/05/05/see-the-difference-developing-a-new-way-to-give.aspx" target="_blank"&gt;presented to the UKAzureNet&lt;/a&gt; group about how we at EMC Consulting had developed the &lt;a href="http://www.seethedifference.org/" target="_blank"&gt;See The Difference&lt;/a&gt; website using many technologies including Windows Azure.&lt;/p&gt;  &lt;p&gt;Part of this session included some information on how we had consumed data we were storing in Windows Azure Table Storage. In this post, I am going to describe the patterns I designed for this in much more detail. &lt;/p&gt;  &lt;h2&gt;The challenge of consuming data from Table Storage&lt;/h2&gt;  &lt;p&gt;The Windows Azure SDK provides an API out of the box to consume table storage data. This API is built on top of WCF Data Services (formerly ADO.NET Data Services), and thus uses OData messaging to execute queries against table storage.&lt;/p&gt;  &lt;p&gt;Table storage uses an implementation of OData with the following key characteristics:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;It&amp;#160; adds table storage specific authorization HTTP headers to each message which map to your Windows Azure account. &lt;/li&gt;    &lt;li&gt;$expand does not work, because table storage provides a simpler, schemaless entity-attribute-value model. &lt;/li&gt;    &lt;li&gt;Entity group transactions only work against a single table in a single partition. &lt;/li&gt;    &lt;li&gt;$orderby does not work, because table storage cannot reorder data (data is ordered on its partition and row keys only). &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;These constraints of table storage provide many challenges as to how you design your table storage implementations. Choice of partition keys, row keys and the granularity of each table is key to designing effect table storage. Other people have already blogged heavily on how to solve such issues.&lt;/p&gt;  &lt;p&gt;When you have successfully designed your table storage model, the next challenge is how to consume this model in an effective manner. Yes the Windows Azure SDK provides you with an API, but you have to figure out the following:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;How can I make this testable using BDD specs? &lt;/li&gt;    &lt;li&gt;How do I handle exceptions and diagnostics? &lt;/li&gt;    &lt;li&gt;How do I make my data access code maintainable? &lt;/li&gt;    &lt;li&gt;How do I encapsulate my table storage access in a way that calling code is ignorant of the implementation? &lt;/li&gt;    &lt;li&gt;How do I work with transactions across entities? &lt;/li&gt;    &lt;li&gt;How can I effectively implement retries and compensation for failure? &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Faced with all these challenges, I ended up architecting a Repository-Mapper-Command pattern, which I will describe below.&lt;/p&gt;  &lt;h2&gt;An overview of the Repository-Mapper-Command pattern&lt;/h2&gt;  &lt;p&gt;The Repository-Mapper-Command pattern is, as the name suggests an implementation of three well known design patterns chained together:&lt;/p&gt;  &lt;table border="1" cellspacing="0" cellpadding="2" width="746"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td&gt;&lt;strong&gt;Pattern&lt;/strong&gt;&lt;/td&gt;        &lt;td&gt;&lt;strong&gt;Formal Definition&lt;/strong&gt;&lt;/td&gt;        &lt;td&gt;&lt;strong&gt;Motivation for use&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;Repository&lt;/td&gt;        &lt;td&gt;Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer. Repository also supports the objective of achieving a clean separation and one-way dependency between the domain and data mapping layers.&lt;/td&gt;        &lt;td&gt;To ensure that calling clients are ignorant of storage implementation details. To provide an API that works using the domain layer objects as currency. To provide a testable layer that enables interactions with data to be articulated using BDD specifications.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;Mapper&lt;/td&gt;        &lt;td&gt;To map from one or more objects to one or more objects.&lt;/td&gt;        &lt;td&gt;To map the contents of domain objects passed into the repository layer into table storage entity objects required for persistence and vice versa.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;Command&lt;/td&gt;        &lt;td&gt;Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.&lt;/td&gt;        &lt;td&gt;The enable the reuse of table storage operations by chaining commands together within a repository. To enable the command interactions being executed within a repository to be tested using BDD specifications.&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;From a calling clients perspective, the repository is called to either retrieve or persist domain object(s). The repository will call mapper(s) classes to translate between domain objects and table storage entities. The repository will call command objects to execute commands against the table storage context. The command objects use table storage entities as currency and not the domain objects.&lt;/p&gt;  &lt;p&gt;For the rest of this article, a Comment domain object will be the subject of this pattern. A comment domain object represents a single comment stored in table storage, which requires retrieval and persistence using this pattern.&lt;/p&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;h2&gt;An important aside on the role of data service context and transactions&lt;/h2&gt;  &lt;p&gt;Before describing each part of this pattern in more detail, it is worth recapping on the role of DataServiceContext in WCF Data Services (used by TableServiceContext).&lt;/p&gt;  &lt;p&gt;The best way to think of DataServiceContext is to consider it as a constructor of an OData message or messages. For example, if you read an entity, update this entity and insert another entity in a single batch operation (by using the MergeOption on SaveChanges), this will execute as a single request-reply message. This message is the boundary of what can be done in a single transaction.&lt;/p&gt;  &lt;p&gt;An instance of a DataServiceContext object is not thread safe. The ramifications of this is that each transaction (unit of work) should be executed using a new instance of the context. It also means that the contents of an acidic transaction needs to be represented in a set of domain objects using composition. For example, if I needed to transactionally insert a customer entity and the customer’s address within the same transaction, the domain model must represent this in a single object graph.&lt;/p&gt;  &lt;p&gt;One final gotcha when using Table Storage entity group transactions; the build in retry policy mechanism build into the table storage client does not work when using entity group transactions; I had to implement my own retry mechanism within a repository and this was a key motivator in implementing the command pattern.&lt;/p&gt;  &lt;p&gt;These facts are fundamental to the design of a repository that uses WCF Data Services such as table storage repositories.&lt;/p&gt;  &lt;h2&gt;The Repository&lt;/h2&gt;  &lt;p&gt;The repository provides an API that works using domain objects, ignorant of the data access and storage technologies used. The interfaces enable the repository to work with an IoC container such as Castle Windsor, which enables repositories to be stubbed out for testing purposes.&lt;/p&gt;  &lt;p&gt;The following diagram illustrates the repository classes and interfaces (click to open it in the original size):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://consultingblogs.emc.com/blogs/simonevans/image_52D79FF2.png" target="_blank"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://consultingblogs.emc.com/blogs/simonevans/image_thumb_1D5EDDCD.png" width="244" height="137" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The table below describes the responsibilities of each class and interface in the repository:&lt;/p&gt;  &lt;table border="1" cellspacing="0" cellpadding="2" width="712"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td&gt;&lt;strong&gt;Interface / Class&lt;/strong&gt;&lt;/td&gt;        &lt;td&gt;&lt;strong&gt;Responsibility&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;ITableStorageRepository&amp;lt;T&amp;gt;&lt;/td&gt;        &lt;td&gt;         &lt;p&gt;Defines a generic interface for all table storage repositories in the system, containing the methods: &lt;/p&gt;          &lt;ul&gt;           &lt;li&gt;Single, for returning a single domain object. &lt;/li&gt;            &lt;li&gt;SelectPartition, for returning a list of domain objects from a table partition. &lt;/li&gt;            &lt;li&gt;Delete, for deleting a single domain object. &lt;/li&gt;            &lt;li&gt;Persist, for adding or updating a single domain object. &lt;/li&gt;         &lt;/ul&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;ICommentRepository&lt;/td&gt;        &lt;td&gt;An implementation of the ITableStorageRepository&amp;lt;T&amp;gt; interface for the Comment domain object. Extensions to the standard methods listed above would be placed in this interface.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;TableStorageRepositoryBase&lt;/td&gt;        &lt;td&gt;         &lt;p&gt;Base class inherited by all Repository classes, responsible for encapsulating the following functionality:&lt;/p&gt;          &lt;ul&gt;           &lt;li&gt;Creation of ApplicationDataServiceContent, including using the correct CloudStorageAccount settings. &lt;/li&gt;            &lt;li&gt;Logging exceptions from Command objects into Azure diagnostics. &lt;/li&gt;         &lt;/ul&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;CommentRepository&lt;/td&gt;        &lt;td&gt;The concrete implementation of the ICommentRepository interface. Inherits the TableStorageRepositoryBase class. Executes commands and uses mappers to translate between domain objects and entity rows.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;ApplicationDataServiceContext&lt;/td&gt;        &lt;td&gt;Provides a strongly typed wrapper over the TableServiceContext object, providing easy access to tables and default settings for tracking options.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;TableServiceContext&lt;/td&gt;        &lt;td&gt;The Azure SDK provided class that is a Table Storage specific implementation of WCF Data Service class DataServiceContext. The TableServiceContext class provides additional plumbing to handle table storage additions to the OData messaging such as adding authentication HTTP headers to messages.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;CloudStorageAccount&lt;/td&gt;        &lt;td&gt;The Azure SDK provided class that represents an Azure storage account as set up via the Azure service portal.&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;The core currency of the repository API is a domain object. The repository exposes methods such as Single to retrieve a single domain object.&lt;/p&gt;  &lt;p&gt;A transaction cannot flow outside of a repository, or outside of a method on a repository. This is good practice regardless of the type of repository, but it is imperative given the nature of the DataServiceContext class. Hence, if a calling client calls persist against two repositories, this will occur as two separate ACID transactions. Failure must be handled using a compensating transaction to leave data in a consistent state.&lt;/p&gt;  &lt;p&gt;Each method on a repository must instantiate its own service context for thread safety. The creation of a service context with the configuration is handled by TableStorageRepositoryBase. The service context instantiated is of type ApplicationDataServiceContext, which provides strongly typed access (via IQueryable&amp;lt;T&amp;gt;) to each table service entity.&lt;/p&gt;  &lt;p&gt;A single repository method will execute one or more commands against a single instance of the service context. Hence, a transaction can flow between commands within a single repository method.&lt;/p&gt;  &lt;p&gt;In order for a command to be executed, the repository must map any domain objects into table storage entity objects using a mapper. Likewise the result of a read command requires a mapper to map the table storage entity back to a domain object.&lt;/p&gt;  &lt;p&gt;The pattern implements a Persist method, rather than add and update. This means the repository is responsible for deciding whether to add or update the domain object(s), based in whether the object has an entity key set or not (when the entity key is null). For example the persist method will execute an AddToObject when the entity key is null.&lt;/p&gt;  &lt;p&gt;The repository catches TableStorageCommandException objects, and actions the exception accordingly, including logging the exception against Windows Azure diagnostics via the TableStorageRepositoryBase.LogCommandException method.&lt;/p&gt;  &lt;h2&gt;The Mapper&lt;/h2&gt;  &lt;p&gt;The follow diagram illustrates the mapper classes and interfaces, including the related domain objects and table storage entities (click to open it in the original size):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://consultingblogs.emc.com/blogs/simonevans/image_5D28C452.png" target="_blank"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://consultingblogs.emc.com/blogs/simonevans/image_thumb_11C9208E.png" width="244" height="135" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The table below describes the responsibilities of each class and interface in the mapper:&lt;/p&gt;  &lt;table border="1" cellspacing="0" cellpadding="2" width="711"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td&gt;&lt;strong&gt;Interface / Class&lt;/strong&gt;&lt;/td&gt;        &lt;td&gt;&lt;strong&gt;Responsibility&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;IMapper&amp;lt;TInput, TOutput&amp;gt;&lt;/td&gt;        &lt;td&gt;The generic interface for mapping from an input entity to an output entity.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;ICommentRowToCommentMapper&lt;/td&gt;        &lt;td&gt;Implements the IMapper&amp;lt;TInput, TOutput&amp;gt; interface, to map from a CommentRow table storage entity to a Comment domain object&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;ICommentToCommentRowMapper&lt;/td&gt;        &lt;td&gt;Implements the IMapper&amp;lt;TInput, TOutput&amp;gt; interface, to map from a Comment domain object to a CommentRow table storage entity.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;CommentRowToCommentMapper&lt;/td&gt;        &lt;td&gt;Concrete implementation of the ICommentRowToCommentMapper interface.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;CommentToCommentRowMapper&lt;/td&gt;        &lt;td&gt;Concrete implementation of the ICommentToCommentRowMapper interface.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;CommentRow&lt;/td&gt;        &lt;td&gt;A strongly typed representation of a single comment row in a table. CommentRow inherits from TableServiceEntity.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;TableServiceEntity&lt;/td&gt;        &lt;td&gt;The Azure SDK provided class which represents a single entity in a table.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;Comment&lt;/td&gt;        &lt;td&gt;The Comment domain object, passed into and out of the repository and used by all other layers of the application architecture.&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;The mapper classes above around mapping between the Comment domain object and the CommentRow table service entity object. The mappers are required to translate between the domain objects surfaced by the repository and the table storage entities executed by commands.&lt;/p&gt;  &lt;h2&gt;The Command&lt;/h2&gt;  &lt;p&gt;The command encapsulates a single operation against table storage and a table service entity (such as a LINQ query). The repository will chain together commands against a single ApplicationDataServiceContext, promoting reuse and improving the maintainability of your code. The command also provides a natural place to handle OData errors thrown as InvalidOperationException objects.&lt;/p&gt;  &lt;p&gt;The follow diagram illustrates the Command classes and interfaces (click to open it in the original size):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://consultingblogs.emc.com/blogs/simonevans/image_6A8ED758.png" target="_blank"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://consultingblogs.emc.com/blogs/simonevans/image_thumb_43548E23.png" width="244" height="120" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The table below describes the responsibilities of each class and interface in the command pattern:&lt;/p&gt;  &lt;table border="1" cellspacing="0" cellpadding="2" width="710"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td&gt;&lt;strong&gt;Interface / Class&lt;/strong&gt;&lt;/td&gt;        &lt;td&gt;&lt;strong&gt;Responsibility&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;TableStorageCommandBase&lt;/td&gt;        &lt;td&gt;Provides implementation of common command logic, such as common exception handling for table storage failures.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;IGetCommentRowsByProjectIdCommand&lt;/td&gt;        &lt;td&gt;The interface for the GetCommentRowsByProjectIdCommand class. Defines the signature for returning a collection of CommentRow table entities from table storage for a single project id.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;IPersistCommentRowCommand&lt;/td&gt;        &lt;td&gt;The interface for the PersistCommentRowCommand class. Defines the signature for persisting (adding or updating) a single CommentRow table entity into table storage.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;GetCommentRowsByProjectIdCommand&lt;/td&gt;        &lt;td&gt;Concrete implementation of the IGetCommentRowsByProjectIdCommand interface. Uses the ApplicationDataServiceContext to execute a LINQ to Data Service query, returning a collection of CommentRow objects for a specific project id.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;PersistCommentRowCommand&lt;/td&gt;        &lt;td&gt;Concrete implementation of the IPersistCommentRowCommand interface. Checks if the CommentRow being persisted has an identity and adds or updates the CommentRow accordingly against the ApplicationDataServiceContext.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;TableStorageCommandException&lt;/td&gt;        &lt;td&gt;Strongly typed exception class used to throw exceptions back to the calling repository.&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Each command represents a single unit of work executed against a shared service context. Commands do not use the domain objects; they are coupled to the table storage implementation details. Each command has an interface so that interactions can be tested in specifications.&lt;/p&gt;  &lt;p&gt;By convention, each command exposes an Execute method, with at least one argument for ApplicationDataServiceContext. If an exception occurs, the TableStorageCommandBase class contains common exception parsing code to translate the OData error into a strongly typed exception (TableStorageCommandException).&lt;/p&gt;  &lt;h2&gt;Summary&lt;/h2&gt;  &lt;p&gt;Use of the Repository-Mapper-Command pattern for Windows Azure table storage enables you to implement storage access with:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Testable BDD specs.&lt;/li&gt;    &lt;li&gt;Diagnostics logging and exception handling.&lt;/li&gt;    &lt;li&gt;Reuse LINQ operations improving maintainability.&lt;/li&gt;    &lt;li&gt;Provide an API that encapsulates all storage implementation details.&lt;/li&gt;    &lt;li&gt;Works with entity group transactions.&lt;/li&gt;    &lt;li&gt;Enables the implementation of retries and compensation where needed.&lt;/li&gt;    &lt;li&gt;Centralizes object dependencies via IoC.&lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;Useful Resources&lt;/h2&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/dd179463.aspx" target="_blank"&gt;Windows Azure table storage concepts.&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://go.microsoft.com/fwlink/?LinkId=153401" target="_blank"&gt;Programming Table Storage Whitepaper&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/jnak/archive/2010/01/06/walkthrough-windows-azure-table-storage-nov-2009-and-later.aspx" target="_blank"&gt;Walkthrough Windows Azure table storage&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=17575" width="1" height="1"&gt;</description><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/Azure+Table+Storage/default.aspx">Azure Table Storage</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/Windows+Azure/default.aspx">Windows Azure</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/Azure/default.aspx">Azure</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/WCF+Data+Services/default.aspx">WCF Data Services</category></item><item><title>See the Difference – Developing a new way to give</title><link>http://consultingblogs.emc.com/simonevans/archive/2010/05/05/see-the-difference-developing-a-new-way-to-give.aspx</link><pubDate>Wed, 05 May 2010 14:15:57 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:17163</guid><dc:creator>simon.evans</dc:creator><slash:comments>1</slash:comments><comments>http://consultingblogs.emc.com/simonevans/comments/17163.aspx</comments><wfw:commentRss>http://consultingblogs.emc.com/simonevans/commentrss.aspx?PostID=17163</wfw:commentRss><description>&lt;p&gt;It is unusual for me to be able to publically blog about project work that I have been doing due to client confidentiality, but my last finished project – See the Difference is different.&lt;/p&gt;  &lt;p&gt;See the Difference is a start up charity site designed to provide a new way of giving, where people donate to projects run by charities that have a specific purpose. The site enables you to see the difference you have made. It launches later this month.&lt;/p&gt;  &lt;p&gt;From a technology perspective, its interesting because it is built on Windows Azure Web Roles, Azure Table Storage and SQL Azure&lt;/p&gt;  &lt;p&gt;On the 15th April James Broome and I presented See the Difference to the &lt;a href="http://ukazurenet.com/" target="_blank"&gt;UKAzureNet&lt;/a&gt; community, which is a user group focussed on the Windows Azure Platform here in the UK.&lt;/p&gt;  &lt;p&gt;The video for the presentation is below:&lt;/p&gt;  &lt;p&gt;&lt;object id="xrPa64b69a011a94b6dbc17ae63dc20e286" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="640" height="360" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"&gt;&lt;param name="data" value="http://exposureroom.com/flash/XRVideoPlayer2.swf?domain=exposureroom.com/&amp;amp;assetId=a64b69a011a94b6dbc17ae63dc20e286&amp;amp;size=md&amp;amp;titleColor=%23ffffff" /&gt;&lt;param name="allowNetworking" value="all" /&gt;&lt;param name="allowScriptAccess" value="always" /&gt;&lt;param name="allowFullScreen" value="True" /&gt;&lt;param name="wmode" value="opaque" /&gt;&lt;param name="src" value="http://exposureroom.com/flash/XRVideoPlayer2.swf?domain=exposureroom.com/&amp;amp;assetId=a64b69a011a94b6dbc17ae63dc20e286&amp;amp;size=md&amp;amp;titleColor=%23ffffff" /&gt;&lt;param name="name" value="xrPlayerEmbededa64b69a011a94b6dbc17ae63dc20e286" /&gt;&lt;param name="allowfullscreen" value="True" /&gt;&lt;embed id="xrPa64b69a011a94b6dbc17ae63dc20e286" type="application/x-shockwave-flash" width="640" height="360" src="http://exposureroom.com/flash/XRVideoPlayer2.swf?domain=exposureroom.com/&amp;amp;assetId=a64b69a011a94b6dbc17ae63dc20e286&amp;amp;size=md&amp;amp;titleColor=%23ffffff" name="xrPlayerEmbededa64b69a011a94b6dbc17ae63dc20e286" wmode="opaque" allowfullscreen="True" allowscriptaccess="always"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;  &lt;p&gt;The presentation is here:&lt;/p&gt;  &lt;div style="width:425px;" id="__ss_3978259"&gt;&lt;strong style="margin:12px 0px 4px;display:block;"&gt;&lt;a title="See the Difference - Developing a new way to give " href="http://www.slideshare.net/guest43bbd1/see-the-difference-developing-a-new-way-to-give"&gt;See the Difference - Developing a new way to give &lt;/a&gt;&lt;/strong&gt;&lt;object id="__sse3978259" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=ukazurenet-100505091024-phpapp01&amp;amp;stripped_title=see-the-difference-developing-a-new-way-to-give" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;param name="allowScriptAccess" value="always" /&gt;&lt;embed name="__sse3978259" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=ukazurenet-100505091024-phpapp01&amp;amp;stripped_title=see-the-difference-developing-a-new-way-to-give" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;    &lt;div style="padding-bottom:12px;padding-left:0px;padding-right:0px;padding-top:5px;"&gt;View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/guest43bbd1"&gt;guest43bbd1&lt;/a&gt;.&lt;/div&gt; &lt;/div&gt;  &lt;p&gt;I will be posting more Azure related content here soon, so watch this space.&lt;/p&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=17163" width="1" height="1"&gt;</description><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/Azure+Table+Storage/default.aspx">Azure Table Storage</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/Windows+Azure/default.aspx">Windows Azure</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/Azure/default.aspx">Azure</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/ASP.NET+MVC/default.aspx">ASP.NET MVC</category></item><item><title>A few Windows Azure events coming up</title><link>http://consultingblogs.emc.com/simonevans/archive/2010/03/26/a-few-windows-azure-events-coming-up.aspx</link><pubDate>Fri, 26 Mar 2010 16:02:25 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:17001</guid><dc:creator>simon.evans</dc:creator><slash:comments>0</slash:comments><comments>http://consultingblogs.emc.com/simonevans/comments/17001.aspx</comments><wfw:commentRss>http://consultingblogs.emc.com/simonevans/commentrss.aspx?PostID=17001</wfw:commentRss><description>&lt;p&gt;There are a few events coming up over the next couple of weeks that I’m speaking at (all in London) with a colleague of mine &lt;a href="http://jamesbroo.me/" target="_blank"&gt;James Broome&lt;/a&gt; about the Windows Azure platform:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="https://msevents.microsoft.com/CUI/InviteOnly.aspx?EventID=80-CB-5A-6A-6E-A4-86-CE-DC-AF-9B-23-E6-CF-42-81&amp;amp;Culture=en-GB" target="_blank"&gt;Microsoft BizSpark Camp March 29th&lt;/a&gt;, targeted at startup businesses&lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-gb/architecture/ee959240.aspx" target="_blank"&gt;Microsoft Architect Insight Conference 2010 April 1st&lt;/a&gt;, targeted at architects&lt;/li&gt;    &lt;li&gt;&lt;a href="http://ukazurenet-techdays.eventbrite.com/" target="_blank"&gt;UK AzureNet User Group, April 15th&lt;/a&gt;, targeted at developers&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Hope to see you there!&lt;/p&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=17001" width="1" height="1"&gt;</description><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/.NET/default.aspx">.NET</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/Windows+Azure/default.aspx">Windows Azure</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/Azure/default.aspx">Azure</category></item><item><title>Common causes of why a Windows Azure web role fails to start</title><link>http://consultingblogs.emc.com/simonevans/archive/2010/03/26/common-causes-of-why-a-windows-azure-web-role-fails-to-start.aspx</link><pubDate>Fri, 26 Mar 2010 15:46:28 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:17000</guid><dc:creator>simon.evans</dc:creator><slash:comments>1</slash:comments><comments>http://consultingblogs.emc.com/simonevans/comments/17000.aspx</comments><wfw:commentRss>http://consultingblogs.emc.com/simonevans/commentrss.aspx?PostID=17000</wfw:commentRss><description>&lt;p&gt;Things have been very quiet on my blog of late. There are several of reasons for this, but the biggest reason is that I have spent most of the last six months really getting to grips with the Windows Azure platform, and working on a real world project using it. So this is the first of several blogs on the subject. &lt;/p&gt;  &lt;p&gt;For all of my Windows Azure blogs I am going to assume that you have at least read the core Window Azure training resources; you should understand key concepts such as web and worker roles, table, blob and queue storage and Azure configuration management. All of my blogs focus on using Windows Azure with .NET and C#, although many of the subjects I will discuss apply to other frameworks and languages a (such as Java).&lt;/p&gt;  &lt;p&gt;I thought I’d start with a subject that, if your first experiences with Windows Azure are like mine, will cause you to waste a lot of time: figuring out why your web role fails to start.&lt;/p&gt;  &lt;h4&gt;What is a web role?&lt;/h4&gt;  &lt;p&gt;Have a look at the documentation here which describes what a web role is:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/dd179341.aspx"&gt;http://msdn.microsoft.com/en-us/library/dd179341.aspx&lt;/a&gt;&lt;/p&gt;  &lt;h4&gt;What are the symptoms of a web role that fails to initialize?&lt;/h4&gt;  &lt;p&gt;When you attempt to start you application via the Azure portal you will see it attempt to initialize. It will then stop, recycle and then attempt to initialize again. This cycle will continue until the service goes into a failed state.&lt;/p&gt;  &lt;h4&gt;Why might a web role fail to initialize correctly?&lt;/h4&gt;  &lt;p&gt;When you deploy your web role to Windows Azure, the fabric generates a VM image based on:&lt;/p&gt;  &lt;p&gt;· The base image of a web role, which contains a Window Server 2008 installation with IIS and .NET framework 3.5 installed. This image is used for all web role instances in any application running in Windows Azure.&lt;/p&gt;  &lt;p&gt;· The settings you provide in the service definition and configuration settings of your Azure project.&lt;/p&gt;  &lt;p&gt;· The .NET assemblies and other artefacts you deploy as part of your service package. &lt;/p&gt;  &lt;p&gt;When you attempt to start your application, the initialization process will run some code called the role entry point. This code runs before anything else in your web site – even before events such as application startup.&lt;/p&gt;  &lt;p&gt;You customize the behaviour of the role entry point by inheriting from the RoleEntryPoint class, provided by the Microsoft.WindowsAzure.ServiceRuntime assembly. It is in here you place code that is specific to your Windows Azure cloud application. Typical code that is placed here includes setting up Azure diagnostics, and access to the Azure configuration system.&lt;/p&gt;  &lt;p&gt;When this initialization process fails, the role will recycle and attempt to restart itself. Because it is here that you place your diagnostics setup, you do not get any logged failures in initialization making it very hard to understand what it wrong.&lt;/p&gt;  &lt;h4&gt;What are the common causes of a web role failing to initialize?&lt;/h4&gt;  &lt;p&gt;The reason that a failing web role can take up so much of your time is because most failures are only apparent when you deploy your application to Windows Azure staging (or production). This is because Dev Fabric is only an approximation of the real Windows Azure environment (see &lt;a href="http://msdn.microsoft.com/en-us/library/ee923628.aspx"&gt;http://msdn.microsoft.com/en-us/library/ee923628.aspx&lt;/a&gt; for a list of how dev fabric differs from Windows Azure).&lt;/p&gt;  &lt;p&gt;The following checklist describes the steps you need to go through in order to ensure that your Windows Azure web role is going to (or at least likely!) to initialize correctly:&lt;/p&gt;  &lt;p&gt;1. Make sure any assemblies that are not part of the Windows Azure base image are set to copy local, by looking at the properties of the references assembly in Visual Studio. This includes assemblies such as System.Web.Mvc (ASP.NET MVC), which are products released by Microsoft since the Azure web role VM image was created. The Windows Azure web role VM includes a base install of .NET 3.5 SP1.&lt;/p&gt;  &lt;p&gt;2. Ensure that your Windows Azure storage endpoint connections strings are correct. By default, a Windows Azure storage endpoint (for table, blob and queue storage) uses HTTPS and not HTTP. If you use HTTP on your dev fabric it will work. When you deploy it, it will fail because the role entry point requires HTTPS. It’s amazing how much time I have wasted staring at a connection string in the service configuration and not realized it is set to use HTTP!&lt;/p&gt;  &lt;p&gt;Ensure you are deploying the correct service configuration file. On our projects, we have stored our production service configuration in blob storage, and reference that file when we update our application. This works well, but can be cumbersome when there are configuration changes required; you can easily end up using the wrong version of the configuration which will likely stop your application initializing.&lt;/p&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=17000" width="1" height="1"&gt;</description><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/.NET/default.aspx">.NET</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/Windows+Azure/default.aspx">Windows Azure</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/Azure/default.aspx">Azure</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/ASP.NET+MVC/default.aspx">ASP.NET MVC</category></item><item><title>ASP.NET Resource Provider for Windows Azure Table Storage</title><link>http://consultingblogs.emc.com/simonevans/archive/2009/11/16/asp-net-resource-provider-for-windows-azure-table-storage.aspx</link><pubDate>Mon, 16 Nov 2009 19:52:01 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:16585</guid><dc:creator>simon.evans</dc:creator><slash:comments>0</slash:comments><comments>http://consultingblogs.emc.com/simonevans/comments/16585.aspx</comments><wfw:commentRss>http://consultingblogs.emc.com/simonevans/commentrss.aspx?PostID=16585</wfw:commentRss><description>&lt;h2&gt;Background&lt;/h2&gt;  &lt;p&gt;Since ASP.NET 2.0, the framework has provided a localization model based on localizing text into RESX files. RESX files are compiled and deployed as part of the website, and referenced through declarative mark-up on your pages, cleanly separating your localized resources from your code.&lt;/p&gt;  &lt;p&gt;Using RESX files to store the resources is highly performant and scalable, because resources are deployed locally with the website, meaning the resources will scale with the number of web servers you run. There are however two main downsides to this approach:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Changes to resource text requires the resource assemblies to be deployed to the web servers in your farm.&lt;/li&gt;    &lt;li&gt;Resource changes need to be done at design time and cannot be achieved at run time.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;These constraints to resources files have led many people to store resources in SQL Server, enabling your to centrally manage and maintain resources at run time without any deployment headaches. This model works really well, and does not require any code changes within your website, because the .NET framework uses a provider based model for swapping out RESX storage for a custom provider (using the globalization configuration section).&lt;/p&gt;  &lt;p&gt;For all the benefits of the SQL Server resource provider approach, it does present one major drawback; SQL Server represents a single instance which must be scaled up rather than out to cater for demand.&lt;/p&gt;  &lt;p&gt;Windows Azure Table storage provides a new storage option for resources. Table storage is non relational (as are resources), providing highly performant storage that scales out on demand. Therefore for resources, table storage provides all the benefits of a SQL Server provider coupled with the scale out capability of RESX files. With resources being stored in the cloud, the ASP.NET website can reside on premise or in a web role in Windows Azure.&lt;/p&gt;  &lt;h2&gt;The Solution&lt;/h2&gt;  &lt;p&gt;The Azure Table Storage Resource Provider source code can be found at:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://localization.codeplex.com"&gt;http://localization.codeplex.com&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The provider implements the standard .NET interfaces for building a resource provider. The entire set of classes used by the solution are shown in the diagram below:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://consultingblogs.emc.com/blogs/simonevans/TableStorageLocalization_4B557AE5.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="TableStorageLocalization" border="0" alt="TableStorageLocalization" src="http://consultingblogs.emc.com/blogs/simonevans/TableStorageLocalization_thumb_05A0CAFA.png" width="403" height="305" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The provider has been built using the Windows Azure SDK July CTP. In order for you to develop with it, you must install the SDK and have the StorageClient assembly. This assembly encapsulates data access to table storage via ADO.NET Data Services.&lt;/p&gt;  &lt;h2&gt;Configuration&lt;/h2&gt;  &lt;p&gt;There are two items you need to configure in order to use the provider:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;You need to ensure your ASP.NET website config file includes the &amp;lt;globalization /&amp;gt; configuration element as demonstrated in the sample web sitein the solution.&lt;/li&gt;    &lt;li&gt;You need to change your Azure configuration file to use your own Azure Table storage account (you can use the development fabric during development).&lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;Table Storage Structure&lt;/h2&gt;  &lt;p&gt;The provider expects two tables to exist in your account:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;GlobalResources, to store global resources&lt;/li&gt;    &lt;li&gt;LocalResources, to store local resources&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;These two tables have the same structure:&lt;/p&gt;  &lt;p&gt;The partition key is the culture name concatenated with the resource set name, encoding to be URI safe. For example:&lt;/p&gt;  &lt;p&gt;en-gbab2fpb61gesb2fsb61mplelocb61lresources.b61spx&lt;/p&gt;  &lt;p&gt;is the partition key for the culture en-GB and the (local) resource set /Pages/SampleLocalResources.aspx. Note that it is stored all in lower case, because access to the partition is case sensitive, so the provider uses a lower case key at all times.&lt;/p&gt;  &lt;p&gt;The table row key is the resource key of the resource. For example, headerliteral.text is the resource key for a literal control with the ID of HeaderLiteral. This resource key identifies the text property of the control. Again, note the provider uses the key stored in lower case.&lt;/p&gt;  &lt;p&gt;The other attributes each table requires are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;CultureName, which contain the name of the culture.&lt;/li&gt;    &lt;li&gt;ResourceSetName, which contains the name of the resource set.&lt;/li&gt;    &lt;li&gt;Data, which contains the actual localized data.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The provider needs to have an invariant set of resources for each localized resource set you implement. This is used as the fall back culture when you do not have a localized resource set for your culture.&lt;/p&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=16585" width="1" height="1"&gt;</description><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/Microsoft/default.aspx">Microsoft</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/Azure+Table+Storage/default.aspx">Azure Table Storage</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/Windows+Azure/default.aspx">Windows Azure</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/Localization/default.aspx">Localization</category></item><item><title>ADO.NET Data Services : Diagnosing problems with your data service</title><link>http://consultingblogs.emc.com/simonevans/archive/2009/03/17/ado-net-data-services-diagnosing-problems-with-your-data-service.aspx</link><pubDate>Tue, 17 Mar 2009 17:37:00 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:14625</guid><dc:creator>simon.evans</dc:creator><slash:comments>0</slash:comments><comments>http://consultingblogs.emc.com/simonevans/comments/14625.aspx</comments><wfw:commentRss>http://consultingblogs.emc.com/simonevans/commentrss.aspx?PostID=14625</wfw:commentRss><description>&lt;P&gt;ADO.NET Data Services is elegant technology that feels very easy to work with. The majority of current scenarios for using ADO.NET Data Services involve exposing an Entity Data Model (EDM) implemented using the ADO.NET Entity Framework.&amp;nbsp; Most of the time, this just works, but it can throw you when you do face problems; how exactly do you diagnose issues in data services, either at design time or in production?&lt;/P&gt;
&lt;P&gt;In this blog post I will cover a common check list that should be followed when things haven’t gone to plan; either the service has never successfully run, or has stopped working in production. I will cover the techniques available to you to diagnose problems with your service.&lt;/P&gt;
&lt;H3&gt;Common Issues&lt;/H3&gt;
&lt;P&gt;Below is a checklist of issues that are common causes of data services not functioning properly.&lt;/P&gt;
&lt;H4&gt;&lt;/H4&gt;
&lt;H4&gt;&lt;/H4&gt;
&lt;H4&gt;Issue 1 : No database connectivity&lt;/H4&gt;
&lt;P&gt;It sounds obvious, but many data services appear not to be working due to an incorrect database connection string.&lt;/P&gt;
&lt;P&gt;Start by checking the connection string that is being used by the Entity Framework. The connection string should be in the &amp;lt;connectionStrings /&amp;gt; section of your service host’s web.config file. Use the server explorer to test the connection credentials. Ensure that the CSDL / MSL / SSDL resources are set to be embedded in the EDMX designer.&lt;/P&gt;
&lt;H4&gt;Issue 2 : Your EDM is using features not supported by ADO.NET Data Services&lt;/H4&gt;
&lt;P&gt;Not everything that you can do in the Entity Data Model is supported by ADO.NET Data Services.&lt;/P&gt;
&lt;P&gt;The first and most common issue here is the use of EDM types that are not supported by data services. A complete list of EDM types supported by ADO.NET Data Services can be found &lt;A href="http://msdn.microsoft.com/en-us/library/cc668779.aspx" target=_blank&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;The second issue you may have when surfacing your EDM is that you have used a form of inheritance not supported by data services. The Entity Framework supports table based inheritance, where the conceptual type must be mapped to a table that represents the sub class. This will only work in the data service if the sub class contains additional properties that are contained in the underlying table.&lt;/P&gt;
&lt;H4&gt;Issue 3 : The database user account does not have access to the required database objects&lt;/H4&gt;
&lt;P&gt;Check that all your database objects (tables, view etc) can be accessed using CRUD based SQL with the account that your are using in your database connection string.&lt;/P&gt;
&lt;H4&gt;Issue 4 : Check you have granted appropriate access to the required entities&lt;/H4&gt;
&lt;P&gt;By default, no entities from an EDM are surfaced by ADO.NET Data Services unless you specifically grant access to the entities. Check your data service’s Initialize method to ensure that you have granted the appropriate access. Conversely, ensure that there is no code grant access to entities or service operations that do not exist in your service.&lt;/P&gt;
&lt;H4&gt;Issue 5 : Invalid custom service operation or query interceptor&lt;/H4&gt;
&lt;P&gt;Custom service operations require the WebGetAttribute to be applied to the method.&lt;/P&gt;
&lt;P&gt;If you have stubbed out your service operation, you must ensure that the operation returns a valid IQueryable object (don’t just return null!).&lt;/P&gt;
&lt;P&gt;For more information on service operations, look at the MSDN documentation &lt;A href="http://msdn.microsoft.com/en-us/library/cc668795.aspx" target=_blank&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;H3&gt;How exceptions are thrown and handled by ADO.NET Data Services&lt;/H3&gt;
&lt;P&gt;ADO.NET Data Services are build on top of a WCF WebHttpBinding channel stack and use the complete WCF infrastructure to expose a service endpoint. Therefore, any &lt;STRONG&gt;unhandled&lt;/STRONG&gt; exceptions from the data service will cause WCF to use its standard fault mechanism to return a response to the client. These faults need to diagnosed using the standard approaches to WCF faults as described later on in this post.&lt;/P&gt;
&lt;P&gt;Exceptions &lt;STRONG&gt;handled&lt;/STRONG&gt; by a data service implementation causes an HTTP 404 error response. This is because ADO.NET Data Services is a good RESTful citizen. If you see this behaviour, you know that an exception has occurred &lt;STRONG&gt;within&lt;/STRONG&gt; the data services runtime.&lt;/P&gt;
&lt;H3&gt;Diagnosing exceptions handled by the data service at runtime&lt;/H3&gt;
&lt;P&gt;As mentioned above, ADO.NET Data Services return a standard HTTP 404 message when the service encounters an exception of any kind. To understand what is going wrong in your service, you need to switch on verbose errors in the service’s initialization. However, this should not be used by a service running in production, because it will stop the service returning a standard HTTP 404 error code. This following service initialization code will switch on verbose errors:&lt;/P&gt;
&lt;P align=left&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Initializes the service. &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;param name="config"&amp;gt;The config.&amp;lt;/param&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;remarks&amp;gt;This method is called only once to initialize service-wide policies.&amp;lt;/remarks&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void InitializeService(IDataServiceConfiguration config) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // other config settings go here... &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#ff0000&gt;&lt;STRONG&gt;config.UseVerboseErrors = false;&lt;/STRONG&gt;&lt;/FONT&gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Unfortunately out of the box, ADO.NET Data Services does not provide a standard configuration section to manage these settings at runtime. Therefore, I have attached (at the very bottom of this post)&amp;nbsp;a custom configuration section that can be used within the InitializeService method to drive these settings through configuration. &lt;/P&gt;
&lt;P&gt;The configuration section will require an entry in your host’s web.config file like the sample below:&lt;/P&gt;
&lt;P align=left&gt;&lt;FONT face="Courier New"&gt;&amp;lt;?xml version="1.0"?&amp;gt; &lt;BR&gt;&amp;lt;configuration&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;configSections&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;sectionGroup name="emc.common"&amp;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;&amp;nbsp;&amp;nbsp; &amp;lt;section name="dataService" type="EMC.Data.Services.Configuration.DataServiceSection, EMC.Data.Services.Configuration"/&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/sectionGroup&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/configSections&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;emc.common&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;dataService&amp;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;lt;serviceSettings useVerboseErrors="false" maxExpandDepth="3" maxExpandCount="10" maxResultsPerCollection="1000" /&amp;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;lt;entitySetAccessRules&amp;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; &amp;lt;add name="*" entitySetRights="All" /&amp;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;lt;/entitySetAccessRules&amp;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;lt;serviceOperationAccessRules&amp;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; &amp;lt;add name="*" serviceOperationRights="All" /&amp;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;lt;/serviceOperationAccessRules&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/dataService&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/emc.common&amp;gt; &lt;BR&gt;&amp;lt;/configuration&amp;gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;The code below illustrates how to wire up the configuration section to the InitializeService method:&lt;/P&gt;
&lt;P align=left&gt;&lt;FONT face="Courier New"&gt;using EMC.Data.Services.Configuration; &lt;/FONT&gt;&lt;/P&gt;
&lt;P align=left&gt;&lt;FONT face="Courier New"&gt;public class MyDataService: DataService&amp;lt;MyEntities&amp;gt; &lt;BR&gt;{&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P align=left&gt;&lt;FONT face="Courier New"&gt;/// &amp;lt;summary&amp;gt; &lt;BR&gt;/// Initializes the service. &lt;BR&gt;/// &amp;lt;/summary&amp;gt; &lt;BR&gt;/// &amp;lt;param name="config"&amp;gt;The config.&amp;lt;/param&amp;gt; &lt;BR&gt;/// &amp;lt;remarks&amp;gt;This method is called only once to initialize service-wide policies.&amp;lt;/remarks&amp;gt; &lt;BR&gt;public static void InitializeService(IDataServiceConfiguration config) &lt;BR&gt;{ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DataServiceSection dataServiceSection = ConfigurationManager.GetSection("emc.common/dataService") as DataServiceSection; &lt;/FONT&gt;&lt;/P&gt;
&lt;P align=left&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (dataServiceSection != null) &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; if (dataServiceSection.ServiceSettings != null) &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; ServiceSettingsElement serviceSettings = dataServiceSection.ServiceSettings; &lt;/FONT&gt;&lt;/P&gt;
&lt;P align=left&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; config.MaxExpandDepth = serviceSettings.MaxExpandDepth; &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; config.UseVerboseErrors = serviceSettings.UseVerboseErrors; &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; config.MaxExpandCount = serviceSettings.MaxExpandCount; &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; config.MaxResultsPerCollection = serviceSettings.MaxResultsPerCollection; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/FONT&gt;&lt;/P&gt;
&lt;P align=left&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (dataServiceSection.EntitySetAccessRules != null) &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; foreach (EntitySetAccessRulesElement element in dataServiceSection.EntitySetAccessRules) &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; config.SetEntitySetAccessRule(element.Name, element.EntitySetRights); &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; } &lt;/FONT&gt;&lt;/P&gt;
&lt;P align=left&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (dataServiceSection.ServiceOperationAccessRules != null) &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; foreach (ServiceOperationAccessRulesElement element in dataServiceSection.ServiceOperationAccessRules) &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; config.SetServiceOperationAccessRule(element.Name, element.ServiceOperationRights); &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; } &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt; &lt;/P&gt;
&lt;P align=left&gt;&lt;FONT face="Courier New"&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;H3&gt;Diagnosing WCF faults&lt;/H3&gt;
&lt;P&gt;If an handled exception is encountered by the WCF channel stack, it will use the standard fault mechanism to respond to the client. By default, the details of the exception will be hidden from the client (again this is how your service should be configured during normal running). This is how it looks in your browser by default when you have a WCF fault in your data service:&lt;/P&gt;
&lt;P&gt;&lt;IMG title=WCFError style="BORDER-RIGHT:0px;BORDER-TOP:0px;DISPLAY:inline;MARGIN-LEFT:0px;BORDER-LEFT:0px;MARGIN-RIGHT:0px;BORDER-BOTTOM:0px;" height=415 alt=WCFError src="http://blogs.conchango.com/blogs/simonevans/WCFError_06930251.png" width=644 border=0&gt; &lt;/P&gt;
&lt;P&gt;In order to see the details of the exception in the response from the service, you need to attach a ServiceBehavior to the data service. This can be done in code by applying a service behaviour attribute to the data service implementation, but again this is hard coded and not what you would want for general good running of your service.&lt;/P&gt;
&lt;P&gt;Unlike ADO.NET Data Services, WCF does provide a standard way of configuring this behaviour at runtime through the web config file. The configuration code below illustrates how you can drive this behaviour through configuration:&lt;/P&gt;
&lt;P align=left&gt;&lt;FONT face="Courier New"&gt;&amp;lt;system.serviceModel&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;services&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;service name="Schedule" behaviorConfiguration="DataServiceBehavior"&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;endpoint binding="webHttpBinding" contract="System.Data.Services.IRequestHandler"/&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/service&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/services&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;behaviors&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;serviceBehaviors&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;behavior name="DataServiceBehavior"&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;serviceDebug includeExceptionDetailInFaults="true"/&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/behavior&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/serviceBehaviors&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/behaviors&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;serviceHostingEnvironment aspNetCompatibilityEnabled="true" /&amp;gt; &lt;BR&gt;&amp;lt;/system.serviceModel&amp;gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;ADO.NET Data Services implements a service contract called IRequestHandler. The name of the service needs to be the fully qualified name of your data service implementation.&lt;/P&gt;
&lt;H3&gt;Using standard WCF messaging diagnostics&lt;/H3&gt;
&lt;P&gt;ADO.NET Data Services also benefit from the excellent support that WCF has for standard trace diagnostics. The following configuration entry illustrates how you can log out WCF’s tracing to a flat file. Again this would only be used when you have problems with your service at runtime:&lt;/P&gt;
&lt;P align=left&gt;&lt;FONT face="Courier New"&gt;&amp;lt;system.diagnostics&amp;gt; &lt;BR&gt;&amp;nbsp; &amp;lt;sources&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;source name="System.ServiceModel.MessageLogging" switchValue="Warning, ActivityTracing" &amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;listeners&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="ServiceModelTraceListener"/&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/listeners&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/source&amp;gt; &lt;/FONT&gt;&lt;/P&gt;
&lt;P align=left&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;source name="System.ServiceModel" switchValue="Verbose,ActivityTracing"&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;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;listeners&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="ServiceModelTraceListener"/&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/listeners&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/source&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;source name="System.Runtime.Serialization" switchValue="Verbose,ActivityTracing"&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;listeners&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="ServiceModelTraceListener"/&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/listeners&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/source&amp;gt; &lt;BR&gt;&amp;nbsp; &amp;lt;/sources&amp;gt; &lt;BR&gt;&amp;nbsp; &amp;lt;sharedListeners&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add initializeData="App_tracelog.svclog" &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; name="ServiceModelTraceListener" traceOutputOptions="Timestamp"/&amp;gt; &lt;BR&gt;&amp;nbsp; &amp;lt;/sharedListeners&amp;gt; &lt;BR&gt;&amp;lt;/system.diagnostics&amp;gt;&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=14625" width="1" height="1"&gt;</description><enclosure url="http://consultingblogs.emc.com/simonevans/attachment/14625.ashx" length="19505" type="application/x-zip-compressed" /><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/.NET/default.aspx">.NET</category><category domain="http://consultingblogs.emc.com/simonevans/archive/tags/WCF/default.aspx">WCF</category></item></channel></rss>
