2

私と職場の友人は、Code First Fluent API を使用して Entity Framework 4 CTP 5 でマッピングを定義するのに苦労しています。関連するデータベースの設定は次のとおりです。

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

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

したがって、人は 0 個以上の電話番号と 0 個以上の電子メール アドレスを持つことができます。電話と電子メールのアドレスは、"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 のコレクションを取得しようとすると、マッピング エラーが発生します。上記のコードのいずれかに明らかに問題がありますか?

ご支援いただきありがとうございます、KurtC

4

1 に答える 1

3

例外は、Contact クラスの 1 つのエンドポイントで 2 つの関連付けを作成しようとしているという事実から発生します。言い換えれば、少なくとも EF CTP5 の時点では、とContact.Personの両方の逆のプロパティはあり得ません。これを修正する 1 つの方法を次に示します。Person.PhonesPerson.Emails

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);
    }
}
于 2011-02-08T02:53:09.817 に答える