实体框架 4 映射问题

发布于 2024-10-16 11:34:46 字数 1900 浏览 0 评论 0原文

我和我的工作朋友在使用 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);
    }
}

当我们尝试针对这些东西运行简单的单元测试时,如果我们只是尝试拉回电话号码或电子邮件地址的集合,一切都很好。但是,如果我们尝试提取 Person 的集合,则会出现映射错误。上面的代码有什么明显的错误吗?

预先感谢您的任何帮助, 库尔特C

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你曾走过我的故事 2024-10-23 11:34:46

例外情况是由于您尝试与 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);
    }
}

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);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文