0

Entity Framework 4.3 経由でアクセスしようとしている既存のデータベースがあります。ほとんどのテーブルとリレーションシップは問題ではありませんでしたが、この一連のテーブルが原因で、答えが見つからないように見えるいくつかの問題が発生しています。

(圧縮された)エンティティは次のとおりです。

お客様

public class Customer
{
    public int CustomerID { get; set; }
    public string Name { get; set; }

    private int addressSourceTypeID = 2;
    [NotMapped]
    public int AddressSourceTypeID { 
        get { return addressSourceTypeID; } 
        set { addressSourceTypeID = value; } }

    public virtual ICollection<User> Users { get; set; }
    public virtual ICollection<Contract> Contracts { get; set; }
    public virtual ICollection<Address> Addresses { get; set; }
}

契約

public class Contract
{
    public int ContractID { get; set; }
    public string Name { get; set; }

    private int addressSourceTypeID = 4;
    [NotMapped]
    public int AddressSourceTypeID { 
        get { return addressSourceTypeID; } 
        set { addressSourceTypeID = value; } }

    public virtual int CustomerID { get; set; }
    public virtual Customer Customer { get; set; }

    //public virtual ICollection<Address> Addresses { get; set; }
}

住所

public class Address
{
    [Key]
    public int AddressID { get; set; }
    public int AddressSourceTypeID { get; set; }

    [ForeignKey("Customer")]
    public int SourceKey { get; set; }

    public virtual Customer Customer { get; set; }
    //public virtual Contract Contract { get; set; }
    public virtual ICollection<Contact> Contacts { get; set; }
}

上にあるのは 2 つのエンティティCustomerでありContract、両方とも子エンティティを持つことができますAddress。現在、Addressエンティティはエンティティの子になるように設定されており、fromCustomerへのリンクがないため、これは正常に機能します。ContractAddress

コメントアウトされたコードセグメントからわかるように、エンティティで行ったのと同じようにContract、エンティティに追加しようとしました。残念ながらこれは機能しませんが、ForeignKey アノテーションで が参照されているため、驚くことではありません。特定のバージョンのエンティティ (つまり) を作成しようとしましたが、複数のエンティティが同じテーブルにバインドしようとするとエラーが発生します。AddressCustomerCustomerAddressAddressCustomerAddress

ModelBuilderEFでも使用してみましたDBContextが、ここでの知識はかなり限られているため、この場合の方法がわかりません。

全体として、私が必要とするのは次のとおりです。

  • 子 Addresses のコレクションを持つ Customer エンティティ。
  • 子アドレスのコレクションを持つコントラクト エンティティ。

これらの「親」テーブルから Address テーブルへのリンクには、次のものが使用されます。

  • Customer: CustomerID => Address: SourceKey AND Customer: AddressSourceTypeID (常に 2) => Address: AddressSourceTypeID.
  • コントラクト: ContractID => アドレス: SourceKey AND コントラクト: AddressSourceTypeID (常に 4) => アドレス: AddressSourceTypeID.

誰かが私を助けたり、正しい方向に向けたりすることができれば、それは素晴らしいことです.

どうもありがとう。

4

1 に答える 1

2

SourceKeyTable per Hierarchy Inheritance を使用して EF に属性を強制させることができます。その後、マッピングが壊れます。またはSourceKey、ビジネス ロジックで を強制し、EF のみがメインAddressクラスを管理するようにすることもできます。

現在の DB スキーマを維持する必要がある場合は、ビジネス ロジックで差別化を強制するSourceKeyことが唯一の選択肢だと思います。

public class Address
{
    public int AddressID { get; set; }
    public int AddressSourceTypeID { get; set; }
    public int SourceKey { get; set; }
    public virtual Contract Contract { get; set; }
    public virtual Customer Customer { get; set; }
}
public class Contract
{
    public Contract()
    {
        this.Addresses = new List<Address>();
    }

    public int ContractID { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Address> Addresses { get; set; }
}
public class Customer
{
    public Customer()
    {
        this.Addresses = new List<Address>();
    }

    public int CustomerID { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Address> Addresses { get; set; }
}

そして、これは流暢なマッピングで:

        modelBuilder.Entity<Address>().HasOptional(t => t.Contract)
            .WithMany(t => t.Addresses)
            .HasForeignKey(d => d.SourceKey);
        modelBuilder.Entity<Address>().HasOptional(t => t.Customer)
            .WithMany(t => t.Addresses)
            .HasForeignKey(d => d.SourceKey);

または - と を作成した場合はCustomerAddressContractAddressTPH 継承を使用して を強制できますがSourceKey、現在、Nav プロパティをマップする方法はありません。

public abstract class Address
{
    [Key]
    public int AddressID { get; set; }
    public int AddressSourceTypeID { get; set; }

    public int SourceKey { get; set; }
}

public class CustomerAddress : Address
{
    public virtual Customer Customer { get; set; }
}

public class ContractAddress : Address
{
    public virtual Contract Contract { get; set; }
}

そして、これはあなたのマッピングとして:

        modelBuilder.Entity<Address>()
            .Map<ContractAddress>(m => m.Requires("AddressSourceTypeID").HasValue(2))
            .Map<CustomerAddress>(m => m.Requires("AddressSourceTypeID").HasValue(4));

これは識別子として強制AddressSourceTypeIDされます。残念ながら、ここでの内訳は、nav プロパティを ContractAddress と Customer Address にマッピングすることです。同じ基本的な問題があったこの関連投稿を参照してください。たぶん、これは少なくとも正しい方向にあなたを始めるでしょう.

于 2012-09-21T15:32:24.320 に答える