Entity Framework 4 mapping issue
Me and my friend at work are having some difficulties defining a mapping in Entity Framework 4 CTP 5 using the Code First Fluent API, and I was hoping someone could point out some obvious dumb mistake we're making. Here's the relevant database setup:
Person
------------
int PersonId (pk)
varchar Name
Contact
--------------
int ContactId (pk)
int ContactTypeId
varchar Text
So, a person can have zero or more phone numbers and zero or more e-mail addresses. Phone and e-mail addresses are stored in a "Contact" table, which is a simple table-per-hierarchy inheritance mapping (with ContactTypeId as the type discriminator). In the code, we have:
public class Person {
public int PersonId { get; set; }
public string Name { get; set; }
public ICollection<Phone> Phones { get; set; }
public ICollection<Email> Emails { get; set; }
}
public abstract class Contact {
public int ContactId { get; set; }
public string Text { get; set; }
public Person Person
}
public class Phone : Contact {}
public class Email : Contact {}
...and for the database mapping we have:
public class ContactMapping : IFluentEntityFrameworkMapping
{
public void OnModelCreating(ModelBuilder modelBuilder)
{
EntityTypeConfiguration<Contact> configuration = modelBuilder.Entity<Contact>();
config.HasKey(c => c.ContactId)
.Map<Email>(e => e.Requires("ContactTypeId").HasValue(1))
.Map<Phone>(p => p.Requires("ContactTypeId").HasValue(2));
}
}
public class PersonMapping : IFluentEntityFrameworkMapping
{
public void OnModelCreating(ModelBuilder modelBuilder)
{
EntityTypeConfiguration<Person> config = modelBuilder.Entity<Person>();
config.HasMany(p => p.Phones).WithRequired(p => p.Person).HasForeignKey(p => p.PersonId);
config.HasMany(p => p.Emails).WithRequired(e => e.Person).HasForeignKey(e => e.PersonId);
}
}
When we try to run simple unit tests against this stuff, if we simply try to pull back collections of phone numbers or email addresses, all is well. But if we try to pull a collection of Persons, we get mapping errors. Is there anything obviously wrong with any of the above code?
Thanks in 开发者_开发百科advance for any assistance, KurtC
The exception comes from the fact that you are trying to create 2 associations with one endpoint on the Contact class. In other words, Contact.Person
is the inverse property for both Person.Phones
and Person.Emails
which is not possible, at least as of EF CTP5. Here is one way to fix this:
public class Person
{
public int PersonId { get; set; }
public string Name { get; set; }
public ICollection<Contact> Contacts { get; set; }
}
public abstract class Contact
{
public int ContactId { get; set; }
public string Text { get; set; }
public int PersonId { get; set; }
public Person Person { get; set; }
}
public class Phone : Contact { }
public class Email : Contact { }
public class Context : DbContext
{
public DbSet<Contact> Contacts { get; set; }
public DbSet<Person> Persons { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Contact>()
.Map<Email>(e => e.Requires("ContactTypeId").HasValue(1))
.Map<Phone>(p => p.Requires("ContactTypeId").HasValue(2));
modelBuilder.Entity<Person>()
.HasMany(p => p.Contacts)
.WithRequired(e => e.Person)
.HasForeignKey(e => e.PersonId);
}
}
精彩评论