实体框架4映射问题

时间:2011-02-07 23:32:55

标签: entity-framework-4 entity-framework-ctp5

我和我的朋友在使用Code First Fluent API定义Entity Framework 4 CTP 5中的映射时遇到了一些困难,我希望有人可以指出我们正在做的一些明显的愚蠢错误。这是相关的数据库设置:

Person
------------
int PersonId (pk)
varchar Name

Contact
--------------
int ContactId (pk)
int ContactTypeId
varchar Text

因此,一个人可以拥有零个或多个电话号码以及零个或多个电子邮件地址。电话和电子邮件地址存储在“Contact”表中,这是一个简单的每层次表继承映射(使用ContactTypeId作为类型鉴别器)。在代码中,我们有:

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 {}

...对于我们的数据库映射:

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);
    }
}

当我们尝试针对这些内容进行简单的单元测试时,如果我们只是尝试撤回电话号码或电子邮件地址的集合,那么一切都很好。但是如果我们试图拉出一组人员,我们会得到映射错误。以上代码中是否有任何明显错误?

预先感谢您的任何帮助, KurtC

1 个答案:

答案 0 :(得分:3)

例外来自于您尝试在Contact类上创建与一个端点的2个关联。换句话说,Contact.PersonPerson.PhonesPerson.Emails的反向属性,这是不可能的,至少从EF CTP5开始。以下是解决此问题的一种方法:

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);
    }
}