Note that there are some explanatory texts on larger screens.

plurals
  1. POEntity splitting when key column has different names?
    primarykey
    data
    text
    <p>I'm using Entity Framework 4.3.1 Code-First and I need to split an entity between two tables. The tables have a primary key shared, and it is 1-to-1, but the columns are not named the same on each table.</p> <p>I don't control the data layout, nor can I request any changes.</p> <p>So for example, the SQL tables could be</p> <p><img src="https://i.stack.imgur.com/p0UVF.png" alt="SQL data tables"></p> <p>And this would be my entity...</p> <pre><code>public class MyEntity { public int Id {get; set;} public string Name {get;set} public string FromAnotherTable {get;set;} } </code></pre> <p>And here is the mapping I have.</p> <pre><code>public class MyEntityMapping : EntityTypeConfiguration&lt;MyEntity&gt; { public MyEntityMapping() { this.Property(e =&gt; e.Id).HasColumnName("ThePrimaryKeyId"); this.Property(e =&gt; e.Name).HasColumnName("MyDatabaseName"); this.Property(e =&gt; e.FromAnothertable).HasColumnName("AnotherTableColumn"); this.Map(m =&gt; { m.Properties(e =&gt; { e.Id, e.Name }); m.ToTable("MainTable"); }); this.Map(m =&gt; { m.Properties(e =&gt; { e.Id, e.FromAnotherTable }); m.ToTable("ExtendedTable"); }); } </code></pre> <p>Since the key shared between them has a different column name, I'm not sure how to map it. This mapping will compile, but fails at runtime because EF emits SQL looking for the "ThePrimaryKeyId" column on the "ExtendedTable" table, which doesn't exist.</p> <p><strong>EDIT</strong> To clarify, what I have defined above can (and does) work if the PK on the "ExtendedTable" followed naming conventions. But it doesn't and I can't change the schema.</p> <p>Basically, what I need EF to emit is a SQL statement like</p> <pre><code>SELECT [e1].*, /*yes, wildcards are bad. doing it here for brevity*/ [e2].* FROM [MainTable] AS [e1] INNER JOIN [ExtendedTable] AS [e2] /*Could be left join, don't care. */ ON [e1].[ThePrimaryKeyId] = [e2].[NotTheSameName] </code></pre> <p>But the only thing it seems to want to emit is </p> <pre><code> SELECT [e1].*, [e2].* FROM [MainTable] AS [e1] INNER JOIN [ExtendedTable] AS [e2] ON [e1].[ThePrimaryKeyId] = [e2].[ThePrimaryKeyId] /* this column doesn't exist */ </code></pre> <p><strong>Edit</strong> I tried the 1-to-1 approach again at NSGaga's suggestion. It didn't work, but here are the results. Entities</p> <pre><code>public class MyEntity { public int Id { get; set; } public int Name { get; set; } public virtual ExtEntity ExtendedProperties { get; set; } } public class ExtEntity { public int Id { get; set; } public string AnotherTableColumn { get; set; } public virtual MyEntity MainEntry { get; set; } } </code></pre> <p>Here are the mapping classes</p> <pre><code>public class MyEntityMapping : EntityTypeConfiguration&lt;MyEntity&gt; { public MyEntityMapping() { this.Property(e =&gt; e.Id).HasColumnName("ThePrimaryKeyId"); this.Property(e =&gt; e.Name).HasColumnName("MyDatabaseName"); this.ToTable("MainTable"); this.HasKey(e =&gt; e.Id); this.HasRequired(e =&gt; e.ExtendedProperties).WithRequiredPrincipal(f =&gt; f.MainEntry); } } public class ExtEntityMapping : EntityTypeConfiguration&lt;ExtEntity&gt; { public ExtEntityMapping() { this.Property(e =&gt; e.Id).HasColumnName("NotTheSameName"); this.Property(e =&gt; e.AnotherTableColumn).HasColumnName("AnotherTableColumn"); this.ToTable("ExtendedTable"); this.HasKey(e =&gt; e.Id); this.HasRequired(e =&gt; e.MainEntry).WithRequiredDependent(f =&gt; f.ExtendedProperties); } } </code></pre> <p>This setup gets the message </p> <pre><code>"Column or attribute 'MyEntity_ThePrimaryKeyId' is not defined in 'ExtendedTable'" </code></pre> <p>Changing the final map line to</p> <pre><code>this.HasRequired(e =&gt; e.MainEntry).WithRequiredDependent(f =&gt; f.ExtendedProperties).Map(m =&gt; M.MapKey("NotTheSameName")); </code></pre> <p>Returns this message</p> <pre><code>"Each property name in a type must be unique. property name 'NotTheSameName' was already defined." </code></pre> <p>Changing the mapped key to use the column from the parent table, <code>MapKey("ThePrimaryKeyId")</code>. returns this message</p> <pre><code>"Column or attribute 'ThePrimaryKeyId' is not defined in 'ExtendedTable'" </code></pre> <p>Removing the <code>Id</code> property from the <code>ExtEntity</code> class throws an error because then the entity doesn't have a defined key.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

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