Note that there are some explanatory texts on larger screens.

plurals
  1. POEF4 code-first: defining object relationships, foreign keys
    text
    copied!<p><strong>&lt; RANT_MODE ></strong></p> <p><em>EF code-first approach is meant to save lots of time but for the time being I've only seen toy examples and spent hours trying to understand how I can make it generate the db I want. But still hoping that Eureka moment :-)</em></p> <p><strong>&lt; RANT_MODE /></strong></p> <p>On to the questions!</p> <h2>Virtual vs. concrete properties</h2> <p>I'm trying to understand how EF maps and retrieves object relationships. When should I mark a property as <code>virtual</code> and when not? (As in <code>public Person Owner { get; set; }</code> vs. <code>public virtual Person Owner { get; set; }</code>.) In the dozens of examples of code-first I've seen they seem to use these interchangably, without much in terms of explanation. What I do know is that navigation properties (<code>public virtual ICollection&lt;Person&gt; Owners { get; set; }</code>) need to be <code>virtual</code> in order to make lazy loading possible (correct..?), but how does that apply in the world of non-collections?</p> <h2>Object relationships and foreign keys</h2> <p>I wasn't able to find any information on whether I should include a foreign key field (<code>public int OwnerId { get; set; }</code>) in addition to the 'main' property I'm interested in (<code>public Person Owner { get; set; }</code>). I tried not to, and EF kindly auto-added an int column named <code>Owner_Id</code> in my table, seemingly understanding what I meant to achieve.</p> <p>In <a href="http://blogs.msdn.com/b/efdesign/archive/2010/06/01/conventions-for-code-first.aspx" rel="noreferrer">Conventions for Code First</a> (section 'Foreign Keys') the EF Team mention that "it is common to include a foreign key property on the dependent end of a relationship", and that "Code First will now infer that any property named '' (i.e. OwnerId) [...] with the same data type as the primary key, represents a foreign key for the relationship". Ie. if I have both EF will know they're related.</p> <p>But is it considered good practice to explicitly specify such properties holding FKs, in addition to 'foreign objects' themselves?</p> <h2>Foreign objects, foreign keys - continued</h2> <p>As I mentioned above, even if I only have <code>public Person Owner { get; set; }</code> in my object (say <code>Event</code>), the table <code>Events</code> will feature an <code>Owner_Id</code> column automagically added by EF. What's more, upon retrieval I will have access to properties of <code>Owner</code>.</p> <p>However, consider the following scenario. I've got two classes:</p> <pre><code>public class Account { public int Id { get; set; } public Person Owner { get; set; } } public class OpenIdAccount : Account { public string Identifier { get; set; } } </code></pre> <p>I want them to be TPT-related. This means manual mapping:</p> <pre><code>modelBuilder.Entity&lt;Account&gt;().MapHierarchy(a =&gt; new { a.Id, Owner_Id = a.Owner.Id }).ToTable("Account"); modelBuilder.Entity&lt;OpenIdAccount&gt;().MapHierarchy(a =&gt; new { a.Id, a.Identifier }).ToTable("OpenIdAccount"); </code></pre> <p>As you may notice, I tried to recreate what EF does with my <code>Owner_Id</code> column. Yet upon retrieval, <code>myAccountInstanceFromDb.Owner</code> is null. Why is that? How do I tell EF that it should do its magic and populate my <code>Owner</code> property?</p> <h2>Pointers, pointers</h2> <p>I will be most grateful if you could clarify the above - got to the point of really wishing to know the answers, but being unable to read yet another article that merely showcases another toy example of how easy it is to play with EF. That said, if you do have an in-depth up-to-date reference on EF's brains, please do post links too.</p> <p>Thank you in advance for your time!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload