<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Entity Framework Design : Mapping</title><link>http://blogs.msdn.com/efdesign/archive/tags/Mapping/default.aspx</link><description>Tags: Mapping</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Code Only – Further Enhancements</title><link>http://blogs.msdn.com/efdesign/archive/2009/10/12/code-only-further-enhancements.aspx</link><pubDate>Mon, 12 Oct 2009 17:31:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9906285</guid><dc:creator>efdesign</dc:creator><slash:comments>26</slash:comments><comments>http://blogs.msdn.com/efdesign/comments/9906285.aspx</comments><wfw:commentRss>http://blogs.msdn.com/efdesign/commentrss.aspx?PostID=9906285</wfw:commentRss><description>&lt;P&gt;We’ve come a long way since the &lt;A href="http://blogs.msdn.com/efdesign/archive/2009/08/03/code-only-enhancements.aspx" mce_href="http://blogs.msdn.com/efdesign/archive/2009/08/03/code-only-enhancements.aspx"&gt;last post on Code-Only&lt;/A&gt;. So it’s high time for another update.&lt;/P&gt;
&lt;P&gt;We’ve been working really hard on Code-Only revving the design, and spotting missing capabilities and responding to feedback both internal and external etc.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;The current plan still holds.&amp;nbsp; Code-Only will not be in .Net 4.0 with the possible exception of the DDL features described in the last post.&amp;nbsp; For that portion, the implementation and requirements are more clear to us, and because making the DDL stuff work requires changes to things already in the .NET framework, and getting provider writers lined up, we are still working hard to get the DDL changes into .NET 4.0.&amp;nbsp; The rest of Code-Only will continue to evolve, and we will ship another preview or two, before getting it rolled into .NET as soon as we can after 4.0 ships. &lt;/P&gt;
&lt;H3&gt;&lt;/H3&gt;
&lt;H3&gt;&lt;/H3&gt;
&lt;H3&gt;API Refactoring&lt;/H3&gt;
&lt;P&gt;As hinted above, we’ve spent a lot of time validating code only against real world scenarios, and thinking about how the customer code hangs together etc. As a results we’ve done some API refactoring.&lt;/P&gt;
&lt;H4&gt;Mappings are now part of Configurations&lt;/H4&gt;
&lt;P&gt;In the last version Mappings were derived from Configurations, which had some strange side-effects on the API. &lt;/P&gt;
&lt;P&gt;We’ve re-arranged things now so that Configurations hold mappings, which are terminated by assignment to a table.&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;builder.Entity&amp;lt;Customer&amp;gt;() &lt;BR&gt;&amp;nbsp;&amp;nbsp; .HasKey(c =&amp;gt; c.ID) &lt;BR&gt;&amp;nbsp;&amp;nbsp; .MapSingleType(c =&amp;gt; new { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cid = c.ID, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; nme = c.Name &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;&amp;nbsp;&amp;nbsp; ) &lt;BR&gt;&amp;nbsp;&amp;nbsp; .ToTable(“dbo.custs”);&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;This maps the Customer entity to the ‘dbo.Custs’ table, the ID property to the cid column, the Name property to the nme column, and registers the ID property as the EntityKey / Primary Key.&lt;/P&gt;
&lt;P&gt;As you can see we’ve also added a helper method called Entity&amp;lt;TEntity&amp;gt;() so that you can fluently create configurations and mappings. You might also have noticed that we have removed RegisterKey and replaced it with HasKey which we feel is more inline with our goal of having an intentional API.&lt;/P&gt;
&lt;H4&gt;TPH mapping syntax no longer violates DRY&lt;/H4&gt;
&lt;P&gt;The previous syntax for specifying a &lt;A href="http://blogs.msdn.com/alexj/archive/2009/04/15/tip-12-choosing-an-inheritance-strategy.aspx" mce_href="http://blogs.msdn.com/alexj/archive/2009/04/15/tip-12-choosing-an-inheritance-strategy.aspx"&gt;TPH&lt;/A&gt; mapping forced you to repeat mappings for columns that could easily have been inherited.&lt;/P&gt;
&lt;P&gt;This was unfortunate because we normally encourage TPH because generally it has the best performance characteristics.&lt;/P&gt;
&lt;P&gt;This is where MapHierarchy() and Case() come in. &lt;/P&gt;
&lt;P&gt;Imagine if we want to write these classes using TPH:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;public class Person{ &lt;BR&gt;&amp;nbsp;&amp;nbsp; public virtual int ID {get;set;} &lt;BR&gt;&amp;nbsp;&amp;nbsp; public virtual string Firstname {get;set;} &lt;BR&gt;&amp;nbsp;&amp;nbsp; public virtual string Surname {get;set;} &lt;BR&gt;} &lt;BR&gt;public class Employee: Person &lt;BR&gt;{ &lt;BR&gt;&amp;nbsp;&amp;nbsp; public virtual Employee Manager {get;set;} &lt;BR&gt;&amp;nbsp;&amp;nbsp; public virtual List&amp;lt;Employee&amp;gt; Reports {get;set;} &lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;You would now do it like this:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;builder &lt;BR&gt;&amp;nbsp;&amp;nbsp; .Entity&amp;lt;Person&amp;gt;() &lt;BR&gt;&amp;nbsp;&amp;nbsp; .HasKey(p =&amp;gt; p.ID) &lt;BR&gt;&amp;nbsp;&amp;nbsp; .MapHierarchy() &lt;BR&gt;&amp;nbsp;&amp;nbsp; .Case&amp;lt;Person&amp;gt;( &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; p =&amp;gt; new { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; p.ID, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; p.Firstname,&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; p.Surname, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; thisIsADiscriminator = “P” &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;&amp;nbsp;&amp;nbsp; ) &lt;BR&gt;&amp;nbsp;&amp;nbsp; .Case&amp;lt;Employee&amp;gt;( &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; e =&amp;gt; new { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; manager = e.Manager.Id &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; thisIsADiscriminator = “E” &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;&amp;nbsp;&amp;nbsp; ) &lt;BR&gt;&amp;nbsp;&amp;nbsp; .ToTable(“dbo.People”);&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;By using Case&amp;lt;&amp;gt; mappings are re-used for derived type, so there is no need to repeat column mappings for ID, Firstname and Surname. &lt;/P&gt;
&lt;P&gt;Which means the Employee Case statement is only responsible for mapping properties and references declared by the Employee class, and for specifying a new discriminator value. &lt;/P&gt;
&lt;P&gt;The discriminator column and values are there so the Entity Framework can distinguish between rows in the dbo.People table that represent Person objects and those that represent Employee objects.&lt;/P&gt;
&lt;H4&gt;MapSingleType and MapHierarchy&lt;/H4&gt;
&lt;P&gt;Because Mappings are now part of the configuration, there is no need to create them independently and assign them. &lt;/P&gt;
&lt;P&gt;You now simply MapXXX() methods on the EntityConfiguration.&lt;/P&gt;
&lt;P&gt;The available mapping methods are:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;MapSingleType(λ) &lt;/LI&gt;
&lt;LI&gt;MapHierarchy(λ) &lt;/LI&gt;
&lt;LI&gt;MapHierarchy().Case&amp;lt;TEntity&amp;gt;(λ).Case&amp;lt;TDerived&amp;gt;(λ). &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;If you know the Entity Frameworks MSL files these correspond to:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Type &lt;/LI&gt;
&lt;LI&gt;OfType &lt;/LI&gt;
&lt;LI&gt;OfType with an addition requirement for a type discriminator &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;These mappings can be combined in many interesting ways, but in general this table shows the recommended way to do most common mappings:&lt;/P&gt;
&lt;TABLE border=1 cellSpacing=0 cellPadding=2 width=426 height=544&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD vAlign=top width=96&gt;&lt;B&gt;Scenario&lt;/B&gt;&lt;/TD&gt;
&lt;TD vAlign=top width=184&gt;&lt;B&gt;Code &lt;BR&gt;&lt;/B&gt;&lt;/TD&gt;
&lt;TD vAlign=top width=268&gt;&lt;B&gt;Notes&lt;/B&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top width=96&gt;No Inheritance&lt;/TD&gt;
&lt;TD vAlign=top width=184&gt;builder.Entity&amp;lt;A&amp;gt;() &lt;BR&gt;&amp;nbsp;&amp;nbsp; .MapSingleType(λ) &lt;BR&gt;&amp;nbsp;&amp;nbsp; .ToTable(“dbo.A”); &lt;BR&gt;&lt;/TD&gt;
&lt;TD vAlign=top width=268&gt;Columns not mapped are not part of the Entity.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top width=96&gt;TPH&lt;/TD&gt;
&lt;TD vAlign=top width=184&gt;builder.Entity&amp;lt;A&amp;gt;() &lt;BR&gt;&amp;nbsp;&amp;nbsp; .MapHierarchy() &lt;BR&gt;&amp;nbsp;&amp;nbsp; .Case&amp;lt;A&amp;gt;(λ) &lt;BR&gt;&amp;nbsp;&amp;nbsp; .Case&amp;lt;B&amp;gt;(λ) &lt;BR&gt;&amp;nbsp;&amp;nbsp; .Case&amp;lt;C&amp;gt;(λ) &lt;BR&gt;&amp;nbsp;&amp;nbsp; .ToTable(“dbo.ABC”); &lt;BR&gt;&lt;/TD&gt;
&lt;TD vAlign=top width=268&gt;Generally each Case expression only maps properties declared by the current type and the discriminator for that type. &lt;BR&gt;&lt;BR&gt;But it is possible to override the mapping for inherited properties if required. &lt;BR&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top width=96&gt;TPT&lt;/TD&gt;
&lt;TD vAlign=top width=184&gt;builder.Entity&amp;lt;A&amp;gt;() &lt;BR&gt;&amp;nbsp;&amp;nbsp; .MapHierarchy(λ) &lt;BR&gt;&amp;nbsp;&amp;nbsp; .ToTable(“dbo.A”); &lt;BR&gt;&lt;BR&gt;builder.Entity&amp;lt;B&amp;gt;() &lt;BR&gt;&amp;nbsp;&amp;nbsp; .MapHierarchy(λ) &lt;BR&gt;&amp;nbsp;&amp;nbsp; .ToTable(“dbo.B”); &lt;BR&gt;&lt;BR&gt;builder.Entity&amp;lt;C&amp;gt;() &lt;BR&gt;&amp;nbsp;&amp;nbsp; .MapHierarchy(λ) &lt;BR&gt;&amp;nbsp;&amp;nbsp; .ToTable(“dbo.C”); &lt;BR&gt;&lt;/TD&gt;
&lt;TD vAlign=top width=268&gt;Each MapHierarchy expression only maps properties declared by the current type, and properties that make up the entity key.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top width=96&gt;TPC&lt;/TD&gt;
&lt;TD vAlign=top width=188&gt;builder.Entity&amp;lt;A&amp;gt;() &lt;BR&gt;&amp;nbsp;&amp;nbsp; .MapSingleType(λ) &lt;BR&gt;&amp;nbsp;&amp;nbsp; .ToTable(“dbo.A”); &lt;BR&gt;&lt;BR&gt;builder.Entity&amp;lt;B&amp;gt;() &lt;BR&gt;&amp;nbsp;&amp;nbsp; .MapSingleType(λ) &lt;BR&gt;&amp;nbsp;&amp;nbsp; .ToTable(“dbo.B”); &lt;BR&gt;&lt;BR&gt;builder.Entity&amp;lt;C&amp;gt;() &lt;BR&gt;&amp;nbsp;&amp;nbsp; .MapSingleType(λ) &lt;BR&gt;&amp;nbsp;&amp;nbsp; .ToTable(“dbo.C”); &lt;BR&gt;&lt;/TD&gt;
&lt;TD vAlign=top width=268&gt;Each MapSingleType expression maps all properties, both those declared by the current type and those inherited.&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;H3&gt;Foreign Keys&lt;/H3&gt;
&lt;P&gt;In Beta2 of .NET 4.0 we added &lt;A href="http://blogs.msdn.com/efdesign/archive/2009/03/16/foreign-keys-in-the-entity-framework.aspx" mce_href="http://blogs.msdn.com/efdesign/archive/2009/03/16/foreign-keys-in-the-entity-framework.aspx"&gt;FK Association Support&lt;/A&gt;, so Code-Only needs a way to link a FK property and an Navigation Property together.&lt;/P&gt;
&lt;P&gt;Given this class:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;public class Product{ &lt;BR&gt;&amp;nbsp;&amp;nbsp; public virtual int ID {get;set;} &lt;BR&gt;&amp;nbsp;&amp;nbsp; public virtual string Name {get;set;} &lt;BR&gt;&amp;nbsp;&amp;nbsp; public virtual Category Category {get;set;} &lt;BR&gt;&amp;nbsp;&amp;nbsp; public virtual int CategoryID {get;set;} &lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;You need to be able to tell code-only that Category.ID and CategoryID should have the same value.&lt;/P&gt;
&lt;P&gt;You do it like this:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;builder.Entity&amp;lt;Product&amp;gt;() &lt;BR&gt;&amp;nbsp;&amp;nbsp; .Relationship(p =&amp;gt; p.Category) &lt;BR&gt;&amp;nbsp;&amp;nbsp; .HasConstraint((p,c) =&amp;gt; p.CategoryID == c.ID);&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;This says that c.ID (i.e. p.Category.ID) must equal p.CategoryID, which tells code-only that p.CategoryID is an FK property and p.Category is a navigation property backed by this FK property.&lt;/P&gt;
&lt;P&gt;HasConstraint(λ) can also be used in conjunction with Relationship(λ).FromProperty(λ) like this:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;builder.Entity&amp;lt;Product&amp;gt;() &lt;BR&gt;&amp;nbsp;&amp;nbsp; .Relationship(p =&amp;gt; p.Category) &lt;BR&gt;&amp;nbsp;&amp;nbsp; .FromProperty(c =&amp;gt; c.Products) &lt;BR&gt;&amp;nbsp;&amp;nbsp; .HasConstraint((p,c) =&amp;gt; p.CategoryID == c.ID);&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verd&gt;Which tells code only that Product.Category and Category.Products are inverses and that Product.CategoryID and Product.Category.ID must be the same, which implies Product.CategoryID is an FK property.&lt;/FONT&gt;&lt;/P&gt;
&lt;H3&gt;Missing Navigation Properties&lt;/H3&gt;
&lt;P&gt;Sometimes you don’t have a navigation property or FK property in the Entity which would naturally hold the FK in the database. For example imagine this scenario:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;public class Product{ &lt;BR&gt;&amp;nbsp;&amp;nbsp; public virtual int ID {get;set;} &lt;BR&gt;&amp;nbsp;&amp;nbsp; public virtual string Name {get;set;} &lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;public class Category{ &lt;BR&gt;&amp;nbsp;&amp;nbsp; public virtual int ID {get;set;} &lt;BR&gt;&amp;nbsp;&amp;nbsp; public virtual string Name {get;set;} &lt;BR&gt;&amp;nbsp;&amp;nbsp; public virtual List&amp;lt;Product&amp;gt; Products {get;set;} &lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Here there is ‘probably’ a one to many relationship between Categories and Products, and that is probably best modeled using an FK in the products table. &lt;/P&gt;
&lt;P&gt;If you start mapping the Product entity you need a way to map the FK column, but there is no reference (i.e. Product.Category) and no FK property (i.e. Product.CategoryID) to map. &lt;/P&gt;
&lt;P&gt;So we added the ability to create a fake navigation property to help out:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;builder.Entity&amp;lt;Product&amp;gt;().MapSingleType( &lt;BR&gt;&amp;nbsp;&amp;nbsp; p =&amp;gt; new { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pid = p.ID, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; nme = p.Name &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cid = EntityMap.Related&amp;lt;Category&amp;gt;(c =&amp;gt; c.Products).ID &lt;BR&gt;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;).ToTable(“dbo.Products”);&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Here the interesting part is EntityMap.Related, it creates a fake navigation property, just so you can use it in the mapping.&lt;/P&gt;
&lt;P&gt;The method signature looks like this:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;public static TEntity Related&amp;lt;TEntity&amp;gt;( &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Expression&amp;lt;Func&amp;lt;TEntity, object&amp;gt; &lt;BR&gt;);&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Notice that this function simply returns TEntity, so in the above mapping fragment, we are mapping the ID property of the Category class to the cid column, in the ‘dbo.Products’ table.&lt;/P&gt;
&lt;H3&gt;Complex Types&lt;/H3&gt;
&lt;P&gt;Code-Only’s default behavior is to ignore properties that are not recognized as either a primitive type or an EntityType. So to support Complex Types we need a mechanism to register one, like this:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;var addressConf = builder.ComplexType&amp;lt;Address&amp;gt;();&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;This returns a ComplexTypeConfiguration through which you can configure the properties of the ComplexType in the same way you configure the properties of an Entity:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;addressConf.Property(a =&amp;gt; a.Street).HasMaxLength(100); &lt;BR&gt;addressConf.Property(a =&amp;gt; a.Zip).HasMaxLength(10);&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Now if an entity is mapped by convention and it has a ComplexType property we will automatically introduce columns for each property of the ComplexType.&lt;/P&gt;
&lt;P&gt;If you want to explicitly map the Entity mapping the ComplexType property is pretty simple too:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;builder.Entity&amp;lt;Person&amp;gt;().MapSingleType( &lt;BR&gt;&amp;nbsp;&amp;nbsp; p =&amp;gt; new { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; p.ID, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fn = p.Firstname, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sn = p.Surname, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; street = p.Address.Street, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; zip = p.Address.Zip &lt;BR&gt;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;);&lt;/FONT&gt;&lt;/P&gt;
&lt;H3&gt;Registering Entity Sets&lt;/H3&gt;
&lt;P&gt;Some of our early CodeOnly adopters wanted to use Code Only without having an specialized ObjectContext, and in theory with is possible:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;builder = contextBuilder.Create&amp;lt;ObjectContext&amp;gt;(); &lt;BR&gt;builder.Entity&amp;lt;Person&amp;gt;().HasKey(p =&amp;gt; p.ID);&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;But what we found is you have no control over the name of the set generated. In this case we will generate an EntitySet called PersonSet, but what if I the name should be People?&lt;/P&gt;
&lt;P&gt;To address this issues we have added this method:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;builder.RegisterSet&amp;lt;Person&amp;gt;(“People”);&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Not only is this useful for specifying names,&amp;nbsp; it also allows you to intentional specify what EntitySets you need. The alternative would be to encode your intent into calls to Entity&amp;lt;TEntity&amp;gt; and Relationship&amp;lt;TRelated&amp;gt;(..).&lt;/P&gt;
&lt;H3&gt;Association Mapping&lt;/H3&gt;
&lt;P&gt;We also need to add support for mapping associations that are not co-located with the Entity. For example take the relationship between Jobs and Candidates. If a candidate can apply for multiple jobs this is a classic example of a many to many relationship. &lt;/P&gt;
&lt;P&gt;If you want to take control of how this relationship is mapped you need a way to specify the mapping for the relationship, like this:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;builder &lt;BR&gt;&amp;nbsp; .Entity&amp;lt;Job&amp;gt;() &lt;BR&gt;&amp;nbsp; .Relationship(job =&amp;gt; job.Applicants) &lt;BR&gt;&amp;nbsp; .FromProperty(candidate =&amp;gt; candidate.Applications) &lt;BR&gt;&amp;nbsp; .Map(“dbo.JobApplications”, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (job,candidate) =&amp;gt; new { &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; applicantId = candidate.Id, &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; jobId = job.Id &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; );&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;This does a number of things, first it indicates that Job.Candidates and Candidate.Applications are opposite ends of the same relationship.&lt;/P&gt;
&lt;P&gt;Then the Map() call indicates that the relationship should be stored in the “dbo.JobApplications” join table, with a compound PK made up of the applicantId and jobId columns. &lt;/P&gt;
&lt;P&gt;The applicantId holds the candidate.Id, and the jobId holds the job.Id, and in both cases Code Only will emit an FK constraint to ensure referential integrity.&amp;nbsp; &lt;/P&gt;
&lt;H3&gt;Interesting Column Names&lt;/H3&gt;
&lt;P&gt;The existing mapping syntax that uses anonymous types for the table and column definitions, limits you to column names that are valid CLR identifiers.&lt;/P&gt;
&lt;P&gt;So for example if you need to map to a column with a space in the name you can’t.&lt;/P&gt;
&lt;P&gt;To rectify this we added an alternate mapping syntax:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;builder.Entity&amp;lt;Product&amp;gt;().MapSingleType( &lt;BR&gt;&amp;nbsp;&amp;nbsp; p =&amp;gt; EntityMap.Row( &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EntityMap.Column(p.ID, “p i d”), &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EntityMap.Column(p.Name), &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EntityMap.Column(p.CategoryId, “c i d”) &lt;BR&gt;&amp;nbsp;&amp;nbsp; ) &lt;BR&gt;).ToTable(“dbo.Products”);&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;This snippet of code, maps the Product entity to the “dbo.Products” table and the ID property to a ‘p i d’ column, the Name property to a Name column and the CategoryId property to the ‘c i d’ column.&lt;/P&gt;
&lt;P&gt;This alternate API has another advantage too: it makes it easier to create mapping expressions programmatically, primarily because you no longer need to create an anonymous type when building the expression. Which is really useful if you want to configure code-only at runtime. &lt;/P&gt;
&lt;H3&gt;Extracting the EDMX&lt;/H3&gt;
&lt;P&gt;We’ve also added the ability to get the EDMX that Code Only is producing internally, either via an XmlWriter or as an XDocument:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;DbConnection connection = // some code to get a connection. &lt;BR&gt;XDocument document = builder.GetEdmx(connection);&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;// or using XmlWriter &lt;BR&gt;var swriter = new StringWriter(); &lt;BR&gt;var xwriter = new XmlTextWriter(swriter); &lt;BR&gt;builder.WriteEdmx(connection, xwriter); &lt;BR&gt;&lt;/FONT&gt;&lt;BR&gt;This is pretty handy if you want to use Code Only to build your model and mappings but then pull them out so you work with the XML and our designer tooling.&lt;/P&gt;
&lt;H3&gt;Setting the StoreType&lt;/H3&gt;
&lt;P&gt;When producing the Storage Model Code Only asks the current database provider to return an appropriate store type for the CLR type and facets specified.&lt;/P&gt;
&lt;P&gt;But some CLR types and facet combinations can map to multiple possible database types. For example fixed length byte[] can map to both binary and timestamp. So in this situation SqlClient returns binary by default. &lt;/P&gt;
&lt;P&gt;But you might need a timestamp:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;builder &lt;BR&gt;&amp;nbsp;&amp;nbsp; .Entity&amp;lt;Order&amp;gt;() &lt;BR&gt;&amp;nbsp;&amp;nbsp; .Property(o =&amp;gt; o.Version)&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp; .HasStoreType(“timestamp”) &lt;BR&gt;&amp;nbsp;&amp;nbsp; .IsComputed();&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;This tells Code Only that the Version property of Order (which is a byte[]) is computed in the database, and is actually a ‘timestamp’ column, which is computed in the database after every insert / update.&lt;/P&gt;
&lt;H3&gt;DDL Provider Model&lt;/H3&gt;
&lt;P&gt;In our &lt;A href="http://blogs.msdn.com/efdesign/archive/2009/10/06/extending-the-entity-framework-provider-model-to-support-ddl.aspx" mce_href="http://blogs.msdn.com/efdesign/archive/2009/10/06/extending-the-entity-framework-provider-model-to-support-ddl.aspx"&gt;last post&lt;/A&gt; we covered our plans around the DDL provider model, so check that out. &lt;/P&gt;
&lt;H3&gt;Summary&lt;/H3&gt;
&lt;P&gt;As you can see Code Only is now looking much more complete.&lt;/P&gt;
&lt;P&gt;But it isn’t completely finished yet, we are still working on the rough edges, so as always we are very interested to get your feedback. &lt;/P&gt;
&lt;P&gt;In particular are there things you think we should add / rename / simplify?&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/alexj" mce_href="http://blogs.msdn.com/alexj"&gt;&lt;B&gt;Alex James&lt;/B&gt;&lt;/A&gt; &lt;BR&gt;Program Manager, Entity Framework Team, Microsoft. &lt;BR&gt;&lt;B&gt;&lt;I&gt;&lt;BR&gt;This post is part of the transparent design exercise in the Entity Framework Team. To understand how it works and how your feedback will be used please look at &lt;/I&gt;&lt;/B&gt;&lt;A href="http://blogs.msdn.com/efdesign/archive/2008/06/23/transparency-in-the-design-process.aspx" mce_href="http://blogs.msdn.com/efdesign/archive/2008/06/23/transparency-in-the-design-process.aspx"&gt;&lt;B&gt;&lt;I&gt;this post&lt;/I&gt;&lt;/B&gt;&lt;/A&gt;&lt;B&gt;&lt;I&gt;. &lt;/I&gt;&lt;/B&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9906285" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/efdesign/archive/tags/Entity+Framework/default.aspx">Entity Framework</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/Providers/default.aspx">Providers</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/Mapping/default.aspx">Mapping</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/CodeOnly/default.aspx">CodeOnly</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/Entity+Framework+Futures/default.aspx">Entity Framework Futures</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/What_2700_s+New/default.aspx">What's New</category></item><item><title>Code Only</title><link>http://blogs.msdn.com/efdesign/archive/2009/06/10/code-only.aspx</link><pubDate>Wed, 10 Jun 2009 23:04:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9724905</guid><dc:creator>efdesign</dc:creator><slash:comments>27</slash:comments><comments>http://blogs.msdn.com/efdesign/comments/9724905.aspx</comments><wfw:commentRss>http://blogs.msdn.com/efdesign/commentrss.aspx?PostID=9724905</wfw:commentRss><description>&lt;P&gt;There are currently two ways to get Entity Framework apps up and running, we call these Database First and Model First respectively. &lt;/P&gt;
&lt;P&gt;Database First has been with us since .NET 3.5 SP1, and involves reverse engineering an Entity Data Model from an existing database.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/adonet/archive/2009/05/12/sneak-preview-model-first-in-the-entity-framework-4-0.aspx" mce_href="http://blogs.msdn.com/adonet/archive/2009/05/12/sneak-preview-model-first-in-the-entity-framework-4-0.aspx"&gt;Model First&lt;/A&gt; is new to Visual Studio 2010/.NET 4.0 and allows you to create an Entity Data Model from scratch and then generate a database and mapping for it.&lt;/P&gt;
&lt;P&gt;However many developers view their Code as their model. &lt;/P&gt;
&lt;P&gt;Ideally these developers just want to write some Domain classes and without ever touching a designer or a piece of XML be able to use those classes with the Entity Framework. &lt;BR&gt;Basically they want to write ‘Code Only’.&lt;/P&gt;
&lt;P&gt;We are pleased to announce that we’ll be shipping a preview of “Code Only” on top of the .NET Framework 4.0 Beta 1 (more on that in the coming days).&lt;/P&gt;
&lt;H5&gt;How it works:&lt;/H5&gt;
&lt;P&gt;To use Code only you simply write some &lt;A href="http://blogs.msdn.com/adonet/archive/2009/05/21/poco-in-the-entity-framework-part-1-the-experience.aspx" mce_href="http://blogs.msdn.com/adonet/archive/2009/05/21/poco-in-the-entity-framework-part-1-the-experience.aspx"&gt;POCO classes&lt;/A&gt;, here is a simple example:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;public class Category &lt;BR&gt;{ &lt;BR&gt;&amp;nbsp;&amp;nbsp; public int ID { get; set; } &lt;BR&gt;&amp;nbsp;&amp;nbsp; public string Name { get; set; } &lt;BR&gt;&amp;nbsp;&amp;nbsp; public List&amp;lt;Product&amp;gt; Products { get; set; } &lt;BR&gt;} &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;public class Product &lt;BR&gt;{ &lt;BR&gt;&amp;nbsp;&amp;nbsp; public int ID { get; set; } &lt;BR&gt;&amp;nbsp;&amp;nbsp; public string Name { get; set; } &lt;BR&gt;&amp;nbsp;&amp;nbsp; public Category Category { get; set; } &lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Then write a class that derives from &lt;FONT face="Courier New"&gt;ObjectContext&lt;/FONT&gt; that describes the shape of your model and how you want to access your POCO classes, so something like this: &lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;public class MyContext : ObjectContext &lt;BR&gt;{ &lt;BR&gt;&amp;nbsp;&amp;nbsp; public MyContext(EntityConnection conn) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; : base(conn){ }&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp; public ObjectSet&amp;lt;Category&amp;gt; Categories { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return base.CreateObjectSet&amp;lt;Category&amp;gt;(); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;&amp;nbsp;&amp;nbsp; public ObjectSet&amp;lt;Product&amp;gt; Products { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return base.CreateObjectSet&amp;lt;Product&amp;gt;(); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;NOTE:&lt;/STRONG&gt; this persistence / EF aware class could easily be in another assembly so you can keep it separate from your nice pristine domain classes.&lt;/P&gt;
&lt;P&gt;At this point you have everything you need from a CLR perspective, but you won’t be able to use the &lt;FONT face="Courier New"&gt;MyContext&lt;/FONT&gt; class without some EF metadata, which is normally stored in the EDMX file. &lt;/P&gt;
&lt;P&gt;But remember Code-Only means there isn’t an EDMX file. &lt;BR&gt;So where do we get the metadata? &lt;BR&gt;That is where the &lt;FONT face="Courier New"&gt;ContextBuilder&lt;/FONT&gt; class comes in:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;SqlConnection connection = …; // some un-opened SqlConnection &lt;BR&gt;MyContext context = ContextBuilder.Create&amp;lt;MyContext&amp;gt;(connection);&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;What is happening here is that the &lt;FONT face="Courier New"&gt;ContextBuilder&lt;/FONT&gt; is looking at the Properties on &lt;FONT face="Courier New"&gt;MyContext&lt;/FONT&gt;, inferring a default Conceptual Model, Storage Model and Mapping by convention, it the uses that metadata plus the &lt;FONT face="Courier New"&gt;SqlConnection&lt;/FONT&gt; you passed in to create an &lt;FONT face="Courier New"&gt;EntityConnection&lt;/FONT&gt;, and finally it constructs an instance of &lt;FONT face="Courier New"&gt;MyContext&lt;/FONT&gt; by passing the &lt;FONT face="Courier New"&gt;EntityConnection&lt;/FONT&gt; to the constructor we created previously.&lt;/P&gt;
&lt;P&gt;Once you have an instance of your context, we ship several extension methods you can use to automatically create a database script, see if the database exists, drops the database, and/or create the database,. For example this code snippet uses two of those extension methods to create the database if it doesn’t already exist.&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;if (!context.DatabaseExists()) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; context.CreateDatabase();&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;The &lt;FONT face="Courier New"&gt;CreateDatabase&lt;/FONT&gt; call looks at the EF metadata, in particular the Storage Model, aka SSDL, and uses it to produce Database Definition Language (or DDL) which it then executes against against the connection. &lt;/P&gt;
&lt;H5&gt;Overriding Conventions&lt;/H5&gt;
&lt;P&gt;In the examples so far everything is done by convention. This is great if you are happy with our conventions. However you may want to override them, for example to register different keys, use different mappings or use a different inheritance strategy etc.&lt;/P&gt;
&lt;P&gt;To override the convention instead of creating an &lt;FONT face="Courier New"&gt;ObjectContext&lt;/FONT&gt; directly you create an instance of a &lt;FONT face="Courier New"&gt;ContextBuilder&lt;/FONT&gt; that you can configure. &lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;var contextBuilder = new ContextBuilder&amp;lt;MyContext&amp;gt;();&lt;/FONT&gt; &lt;BR&gt;&lt;BR&gt;In the first Feature CTP, Code Only provides the ability to override how the key properties are inferred:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;contextBuilder.RegisterKey((Product p) =&amp;gt; p.ID);&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;This code tells the builder that the key of &lt;FONT face="Courier New"&gt;Product&lt;/FONT&gt; is its &lt;FONT face="Courier New"&gt;ID&lt;/FONT&gt; property.&lt;/P&gt;
&lt;P&gt;When you’ve finished configuring how you want your model and mappings to work in your code, you create an instance of your context, this time by calling Create on the builder instance you have been configuring:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;MyContext context = contextBuilder.Create(connection);&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;It is that simple.&lt;/P&gt;
&lt;P&gt;Over time the features of the &lt;FONT face="Courier New"&gt;ContextBuilder&lt;/FONT&gt; will grow so you will be able to setup custom mappings, mark properties as transient, setup up Facets (e.g. &lt;FONT face="Courier New"&gt;MaxLength&lt;/FONT&gt;), change inheritance strategies, link properties that are the inverse of each other together (e.g. &lt;FONT face="Courier New"&gt;product.Category&lt;/FONT&gt; and &lt;FONT face="Courier New"&gt;category.Products&lt;/FONT&gt;) and more. In fact here is an example of the sort of thing we are aiming to support for the next release of the Feature CTP: &lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;builder[“dbo.prds”] =&amp;nbsp; &lt;BR&gt;&amp;nbsp; from c in builder.OfType&amp;lt;Product&amp;gt;() &lt;BR&gt;&amp;nbsp; select new { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; pcode = p.ID, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; p.Name, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cat = p.Category.ID &lt;BR&gt;&amp;nbsp; } &lt;BR&gt;);&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;This snippet:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Maps &lt;FONT face="Courier New"&gt;Product&lt;/FONT&gt; entities to the ‘&lt;FONT face="Courier New"&gt;prds&lt;/FONT&gt;’ table. &lt;/LI&gt;
&lt;LI&gt;Maps &lt;FONT face="Courier New"&gt;Product.ID&lt;/FONT&gt; to a ‘&lt;FONT face="Courier New"&gt;pcode&lt;/FONT&gt;’ column. &lt;/LI&gt;
&lt;LI&gt;Maps &lt;FONT face="Courier New"&gt;Product.Name&lt;/FONT&gt; to a ‘&lt;FONT face="Courier New"&gt;Name&lt;/FONT&gt;’ column. &lt;/LI&gt;
&lt;LI&gt;Maps the FK under the &lt;FONT face="Courier New"&gt;Product.Category&lt;/FONT&gt; relationship to the ‘&lt;FONT face="Courier New"&gt;cat&lt;/FONT&gt;’ column. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Here is another example that does basic &lt;A href="http://blogs.msdn.com/alexj/archive/2009/04/15/tip-12-choosing-an-inheritance-strategy.aspx" mce_href="http://blogs.msdn.com/alexj/archive/2009/04/15/tip-12-choosing-an-inheritance-strategy.aspx"&gt;TPH&lt;/A&gt; inheritance:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;builder[“dbo.Cars”] = ( &lt;BR&gt;&amp;nbsp; from b in builder.OfTypeOnly&amp;lt;Car&amp;gt;() &lt;BR&gt;&amp;nbsp; select new { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; id = b.CID.AsKey(), &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b.Color, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b.Manufacturer, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; disc = “C” &lt;BR&gt;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;).Merge( &lt;BR&gt;&amp;nbsp; from s in builder.OfType&amp;lt;SportsCar&amp;gt;() &lt;BR&gt;&amp;nbsp; select new { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; id = s.CID.AsKey(),&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; s.Color,&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; s.Manufacturer,&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; disc = “S”,&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; hp = s.HorsePower,&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tq = s.Torque &lt;BR&gt;&amp;nbsp; } &lt;BR&gt;);&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;These two examples just scratch the surface of what we are planning on doing, hopefully though they give you a sense of where we are heading. &lt;/P&gt;
&lt;P&gt;We are super excited about Code Only. But as of right now our plans to support overriding conventions aren’t finalized, so we’d love to get your feedback, this really is your chance to help us get it right.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;&lt;A href="http://blogs.msdn.com/alexj" mce_href="http://blogs.msdn.com/alexj"&gt;Alex James&lt;/A&gt;&lt;/B&gt;, &lt;BR&gt;Program Manager, Entity Framework Team, Microsoft &lt;/P&gt;
&lt;P&gt;&lt;EM&gt;&lt;B&gt;This post is part of the transparent design exercise in the Entity Framework Team. To understand how it works and how your feedback will be used please look at &lt;/B&gt;&lt;/EM&gt;&lt;A href="http://blogs.msdn.com/efdesign/archive/2008/06/23/transparency-in-the-design-process.aspx" mce_href="http://blogs.msdn.com/efdesign/archive/2008/06/23/transparency-in-the-design-process.aspx"&gt;&lt;EM&gt;&lt;B&gt;this post&lt;/B&gt;&lt;/EM&gt;&lt;/A&gt;&lt;EM&gt;&lt;B&gt;. &lt;/B&gt;&lt;/EM&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9724905" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/efdesign/archive/tags/Entity+Framework/default.aspx">Entity Framework</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/Mapping/default.aspx">Mapping</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/ObjectServices/default.aspx">ObjectServices</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/CodeOnly/default.aspx">CodeOnly</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/Entity+Framework+Futures/default.aspx">Entity Framework Futures</category></item><item><title>Using Stored Procedures to load structured data.</title><link>http://blogs.msdn.com/efdesign/archive/2008/07/18/using-stored-procedures-to-get-load-structured-data.aspx</link><pubDate>Fri, 18 Jul 2008 20:59:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8750530</guid><dc:creator>efdesign</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/efdesign/comments/8750530.aspx</comments><wfw:commentRss>http://blogs.msdn.com/efdesign/commentrss.aspx?PostID=8750530</wfw:commentRss><description>&lt;p&gt;V1 of the Entity Framework allows you to use stored procedures in two main ways:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Mapping Create, Update and Delete entity operations to appropriate stored procedures. &lt;/li&gt;
&lt;li&gt;Doing a FunctionImport that allows you to return an enumeration of Entities* &lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;Now the thing is, in order to return an enumeration of&amp;nbsp;Entities, you have to map the Entity too.&lt;/p&gt;
&lt;p&gt;Why? &lt;/p&gt;
&lt;p&gt;Well in V1 FunctionImport attaches the returned entities, so you can make and save changes.&lt;/p&gt;
&lt;p&gt;But of course sometimes you don't want that functionality, you just want a structured way of moving information around, so it is a shame to be required to do the mapping too.&lt;/p&gt;
&lt;p&gt;This leaves us two possibilities for V2.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Allowing FunctionImports to return unattached/untracked Entities. &lt;/li&gt;
&lt;li&gt;Allowing FunctionImports to return ComplexTypes. &lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;The ComplexTypes option is the topic of the following one-pager by Asad a Program Manager on the Entity Framework team:&lt;/p&gt;
&lt;h3&gt;Scenario:&lt;/h3&gt;
&lt;h4&gt;Customer Goal:&lt;/h4&gt;
&lt;p&gt;The customer wants to do something like this in their .NET code:&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; color: blue;" courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;public&lt;/span&gt;&lt;span style="font-size: 10pt;" courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;CustomerInfo&lt;/span&gt; GetCustomerInfo(&lt;span style="color: blue;"&gt;int&lt;/span&gt; Id) &lt;br&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;" courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;{ &lt;br&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;" courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; (&lt;span style="color: rgb(43, 145, 175);"&gt;NorthwindEntities &lt;/span&gt;ctx = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;NorthwindEntities&lt;/span&gt;()) &lt;br&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;" courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{ &lt;br&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;" courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;CustomerInfo&lt;/span&gt; info = ctx.GetCustomerInfoById(Id).FirstOrDefault(); &lt;br&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;" courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt; info; &lt;br&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;" courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;} &lt;br&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; line-height: 115%;" courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Without needing to create mappings&amp;nbsp;etc,&amp;nbsp;as this lowers the&amp;nbsp;level of friction inherent in using stored procedures for queries with the Entity Framework.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;NB: today we only support Collection(Type) as the return type of the FunctionImport, which means it results in an Enumeration, hence the call to FirstOrDefault(). A separate work item is required to support returning just one ComplexType (or EntityType) rather than collections.&lt;/p&gt;
&lt;h3&gt;Detailed Scenario walk through:&lt;/h3&gt;
&lt;h4&gt;&lt;span style=""&gt;User defines a Stored Procedure in store:&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Tahoma','sans-serif';"&gt; &lt;/span&gt;&lt;/h4&gt;
&lt;h4&gt;&lt;span style="font-size: 10pt; font-family: 'Tahoma','sans-serif';"&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;Create&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New';"&gt; &lt;span style="color: blue;"&gt;Procedure&lt;/span&gt; GetCustomerInfoById&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New';"&gt;&lt;span style="color: gray;"&gt;( &lt;br&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New';"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;@Id &lt;span style="color: blue;"&gt;int &lt;br&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New';"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: gray;"&gt;) &lt;br&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;As &lt;br&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New';"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;SELECT&lt;/span&gt; first_name &lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;As &lt;/span&gt;Firstname&lt;span style="color: gray;"&gt;,&lt;/span&gt; last_name &lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;As &lt;/span&gt;Lastname&lt;span style="color: gray;"&gt;,&lt;/span&gt; city &lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;As &lt;/span&gt;City&amp;nbsp; &lt;br&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New';"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;FROM&lt;/span&gt; CustomerTable &lt;br&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New';"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;WHERE&lt;/span&gt; id &lt;span style="color: gray;"&gt;=&lt;/span&gt; @Id&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Tahoma','sans-serif';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;h4&gt;Complex type definition in EDM:&lt;/h4&gt;
&lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal;"&gt;&lt;span style="font-size: 11pt;"&gt;User wants to map the result set from this stored procedure to a Complex type “CustomerData” defined in Entity Data Model as: &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(163, 21, 21); font-family: 'Courier New';"&gt;ComplexType&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: red; font-family: 'Courier New';"&gt;Name&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;=&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New';"&gt;"&lt;span style="color: blue;"&gt;CustomerData&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt; &lt;br&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(163, 21, 21); font-family: 'Courier New';"&gt;Property&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: red; font-family: 'Courier New';"&gt;Name&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;=&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New';"&gt;"&lt;span style="color: blue;"&gt;Firstname&lt;/span&gt;"&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;Type&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;String&lt;/span&gt;"&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;MaxLength&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;50&lt;/span&gt;"&lt;span style="color: blue;"&gt; /&amp;gt; &lt;br&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(163, 21, 21); font-family: 'Courier New';"&gt;Property&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: red; font-family: 'Courier New';"&gt;Name&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;=&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New';"&gt;"&lt;font color="#0000ff"&gt;Lastname&lt;/font&gt;"&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;Type&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;String&lt;/span&gt;"&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;MaxLength&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;50&lt;/span&gt;"&lt;span style="color: blue;"&gt; /&amp;gt; &lt;br&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(163, 21, 21); font-family: 'Courier New';"&gt;Property&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: red; font-family: 'Courier New';"&gt;Name&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;=&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New';"&gt;"C&lt;span style="color: blue;"&gt;ity&lt;/span&gt;"&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;Type&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;String&lt;/span&gt;"&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;MaxLength&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;50&lt;/span&gt;"&lt;span style="color: blue;"&gt; /&amp;gt; &lt;br&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(163, 21, 21); font-family: 'Courier New';"&gt;ComplexType&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Tahoma','sans-serif';"&gt; &lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;The mapping involves following three steps:&lt;/h3&gt;
&lt;h4&gt;Define import function definition in SSDL:&lt;/h4&gt;
&lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(163, 21, 21); font-family: 'Courier New';"&gt;Function&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: red; font-family: 'Courier New';"&gt;Name&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;=&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New';"&gt;"&lt;span style="color: blue;"&gt;GetCustomerInfoById&lt;/span&gt;"&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;Aggregate&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;false&lt;/span&gt;"&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;BuiltIn&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;false&lt;/span&gt;"&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: red; font-family: 'Courier New';"&gt;NiladicFunction&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;=&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New';"&gt;"&lt;span style="color: blue;"&gt;false&lt;/span&gt;"&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;IsComposable&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;false&lt;/span&gt;"&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: red; font-family: 'Courier New';"&gt;ParameterTypeSemantics&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;=&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New';"&gt;"&lt;span style="color: blue;"&gt;AllowImplicitConversion&lt;/span&gt;"&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;Schema&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;dbo&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt; &lt;br&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(163, 21, 21); font-family: 'Courier New';"&gt;Parameter&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: red; font-family: 'Courier New';"&gt;Name&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;=&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New';"&gt;"&lt;span style="color: blue;"&gt;Id&lt;/span&gt;"&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;Type&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;int&lt;/span&gt;"&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;Mode&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;In&lt;/span&gt;"&lt;span style="color: blue;"&gt; /&amp;gt;&lt;br&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(163, 21, 21); font-family: 'Courier New';"&gt;Function&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;&amp;gt; &lt;/span&gt;&lt;/p&gt;
&lt;h4&gt;Expose function definition in CSDL schema file&lt;/h4&gt;
&lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: 'Tahoma','sans-serif';"&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(163, 21, 21); font-family: 'Courier New';"&gt;EntityContainer&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: red; font-family: 'Courier New';"&gt;Name&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;=&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New';"&gt;"&lt;span style="color: blue;"&gt;CustomerEntityContainer&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&amp;nbsp;&lt;br&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(163, 21, 21); font-family: 'Courier New';"&gt;FunctionImport&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: red; font-family: 'Courier New';"&gt;Name&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;=&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New';"&gt;"&lt;span style="color: blue;"&gt;GetCustomerInfoById&lt;/span&gt;"&amp;nbsp;&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;&lt;span style=""&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: red; font-family: 'Courier New';"&gt;ReturnType&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;=&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New';"&gt;"&lt;span style="color: blue;"&gt;Collection(Self.CustomerData)&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(163, 21, 21); font-family: 'Courier New';"&gt;Parameter&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: red; font-family: 'Courier New';"&gt;Name&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;=&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New';"&gt;"&lt;span style="color: blue;"&gt;Id&lt;/span&gt;"&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;Mode&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;In&lt;/span&gt;"&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;Type&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;Int32&lt;/span&gt;"&lt;span style="color: blue;"&gt; /&amp;gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(163, 21, 21); font-family: 'Courier New';"&gt;FunctionImport&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;&amp;gt; &lt;br&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(163, 21, 21); font-family: 'Courier New';"&gt;EntityContainer&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;&amp;gt;&lt;/span&gt; 
&lt;h4&gt;&lt;a class="" title="_Toc201594026" name="_Toc201594026"&gt;&lt;/a&gt;&lt;span style=""&gt;Define mapping (convention based) MSL file:&lt;/span&gt;&lt;span style=""&gt; &lt;/span&gt;&lt;/h4&gt;
&lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(163, 21, 21); font-family: 'Courier New';"&gt;EntityContainerMapping&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: red; font-family: 'Courier New';"&gt;StorageEntityContainer&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;=&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New';"&gt;"&lt;span style="color: blue;"&gt;StoreContainer&lt;/span&gt;"&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: red; font-family: 'Courier New';"&gt;CdmEntityContainer&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;=&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New';"&gt;"&lt;span style="color: blue;"&gt;CustomerEntityContainer&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&amp;nbsp;&lt;br&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(163, 21, 21); font-family: 'Courier New';"&gt;FunctionImportMapping&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: red; font-family: 'Courier New';"&gt;FunctionImportName&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;=&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New';"&gt;"&lt;span style="color: blue;"&gt;GetCustomerInfoById&lt;/span&gt;"&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: red; font-family: 'Courier New';"&gt;FunctionName&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;=&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New';"&gt;"&lt;span style="color: blue;"&gt;StoreNamespace.GetCustomerInfoById&lt;/span&gt;"&lt;span style="color: blue;"&gt; /&amp;gt; &lt;br&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(163, 21, 21); font-family: 'Courier New';"&gt;EntityContainerMapping&lt;/span&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New';"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Tahoma','sans-serif';"&gt; &lt;/span&gt;
&lt;/p&gt;&lt;h3&gt;Design Details:&lt;/h3&gt;
&lt;p class="MsoListParagraphCxSpFirst" style="margin: 0in 0in 0pt 21.75pt; text-indent: -0.25in; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: 'Tahoma','sans-serif';"&gt;&lt;span style=""&gt;-&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 11pt;"&gt;Mapping between Complex type and result type is by convention. &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0pt 21.75pt; text-indent: -0.25in; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: 'Tahoma','sans-serif';"&gt;&lt;span style=""&gt;-&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 11pt;"&gt;Explicit property to column name mapping is not supported. &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0pt 21.75pt; text-indent: -0.25in; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: 'Tahoma','sans-serif';"&gt;&lt;span style=""&gt;-&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 11pt;"&gt;The result from the stored procedure has to exactly match the shape and the property names of the complex types. &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoListParagraphCxSpLast" style="margin: 0in 0in 0pt 21.75pt; text-indent: -0.25in; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: 'Tahoma','sans-serif';"&gt;&lt;span style=""&gt;-&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 11pt;"&gt;In EDM the result is captured in a Complex type therefore no EntitySet definition or mapping is required.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;Assumptions/suppositions:&lt;/h3&gt;
&lt;p class="MsoListParagraph" style="margin: 0in 0in 0pt 21.75pt; text-indent: -0.25in; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: 'Tahoma','sans-serif';"&gt;&lt;span style=""&gt;-&lt;span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 11pt;"&gt;A future work item (covered by a separate feature entry) would enable richer mapping capability by allowing column renames. However for now Convention based mapping is the only supported feature.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Looking forward to hearing your feedback.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/alexj" mce_href="http://blogs.msdn.com/alexj"&gt;&lt;b&gt;Alex James&lt;/b&gt;&lt;/a&gt; &lt;br&gt;Program Manager, &lt;br&gt;Entity Framework Team&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;i&gt;This post is part of the transparent design exercise in the Entity Framework Team. To understand how it works and how your feedback will be used please look at &lt;/i&gt;&lt;/b&gt;&lt;b&gt;&lt;i&gt;&lt;a href="http://blogs.msdn.com/efdesign/archive/2008/06/23/transparency-in-the-design-process.aspx" mce_href="http://blogs.msdn.com/efdesign/archive/2008/06/23/transparency-in-the-design-process.aspx"&gt;this post&lt;/a&gt;&lt;/i&gt;&lt;/b&gt;&lt;b&gt;&lt;i&gt;. &lt;/i&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;*In V1 it is also possible to do a FunctionImport that returns a scalar value, but this FunctionImport is not available in Object Services, if you want to use it you have to drop down to eSQL in the EntityServices layer.&amp;nbsp; &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8750530" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/efdesign/archive/tags/Entity+Framework/default.aspx">Entity Framework</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/EDM/default.aspx">EDM</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/Stored+Procedures/default.aspx">Stored Procedures</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/Mapping/default.aspx">Mapping</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/Entity+Framework+4/default.aspx">Entity Framework 4</category></item></channel></rss>