问题
I know a lot of people is asking about one-to-one relationships on EF 4.1 but I can't seem to find an answer for this problem.
I have these POCO classes:
public class Contact
{
public decimal nCont_id { get; set; }
public virtual WebsiteMembership WebsiteMembership { get; set; }
//a bunch of other properties
}
public class WebsiteMembership
{
public int WebsiteMembershipId { get; set; }
public virtual Contact Contact { get; set; }
}
Website membership's primary key (WebsiteMembershipId) is also a foreign key that references Contact's nCont_id.
I'm trying to set this up using the fluent API:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//This is being done because of the unconventional column names I have to live with
modelBuilder.Conventions.Remove<NavigationPropertyNameForeignKeyDiscoveryConvention>();
//bunch of other stuff
modelBuilder.Entity<Contact>().ToTable("contacts");
modelBuilder.Entity<Contact>().HasKey(b => b.nCont_id);
modelBuilder.Entity<Contact>().HasOptional(b => b.WebsiteMembership).WithRequired(b => b.Contact).Map(b => b.MapKey("WebsiteMembershipId"));
modelBuilder.Entity<WebsiteMembership>().ToTable("WebsiteMembership");
modelBuilder.Entity<WebsiteMembership>().HasKey(b => b.WebsiteMembershipId);
}
But I get an exception when I try doing:
var websiteMembership = context.WebsiteMemberships.Where(c => c.WebsiteMembershipId == 1645942).FirstOrDefault();
Exception:
Schema specified is not valid. Errors: (263,6) : error 0019: Each property name in a type must be unique. Property name 'WebsiteMembershipId' was already defined.
Does this mean I can't set the same primary key as a foreign key on EF CodeFirst? Or I'm doing something wrong here? Would it work if the primary key wasn't the same column as the foreign key?
Advice is very much appreciated!
回答1:
I think when you define this mapping...
modelBuilder.Entity<Contact>()
.HasOptional(b => b.WebsiteMembership)
.WithRequired(b => b.Contact)
.Map(b => b.MapKey("WebsiteMembershipId"));
...you implicitely define what's the principal and what's the dependent of the relationship. Obviously Contact
is the principal because having the WebsiteMembership
property set is optional for the Contact
, it can be stored without the WebsiteMembership
. The WebsiteMembership
entity on the other side has a required reference to a Contact
which means it depends on the Contact
.
The principal (Contact
) is the entity with the primary key, the dependent (WebsiteMembership
) the entity with the foreign key. So, when you use MapKey
to set the name WebsiteMembershipId
of the foreign key column you define a column for the table WebsiteMembership
, not for Contact
. But WebsiteMembership
already has a property called WebsiteMembershipId
. (I believe that's the point where EF complains that a "Property name 'WebsiteMembershipId' was already defined.) In a one-to-many relationship the foreign key would be the ContactId
as a separate property/column and you would have to use HasForeignKey
instead of MapKey
. But in a one-to-one relationship it is clear that the foreign key is the primary key at the same time, so you don't need to define the foreign key at all.
To cut a long story short: Just remove MapKey
:
modelBuilder.Entity<Contact>()
.HasOptional(b => b.WebsiteMembership)
.WithRequired(b => b.Contact);
(But now I am curious if you can define a relationship between an int
and a decimal
property or if you get the next error.)
来源:https://stackoverflow.com/questions/8015056/ef-4-1-code-first-mapping-a-one-to-one-relationship-with-non-standard-column-n