4

Entity Framework 5 の使用

だから私は顧客を持っています。顧客は多くのアドレスを持つことができますが、少なくとも 1 つです。アドレスの 1 つもプライマリ アドレスとして設定されます (必須)。さまざまなマッピングを試しましたが、これまでのところ、ビルド時またはデータベースのシード時にエラーが発生します。

お客様:

public class Customer
{
    public int CustomerId { get; set;}
    public String CustomerName { get; set; }
    public int PrimaryAddressId { get; set; }
    public virtual CustomerAddress PrimaryAddress { get; set; }
    public virtual ICollection<CustomerAddress> CustomerAddresses { get; set; }    
}

住所:

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

私のマッピングのこの部分は正しく機能しています。CustomerAddress にあります。

        this.HasRequired(c => c.Customer)
            .WithMany(d => d.CustomerAddresses)
            .HasForeignKey(c => c.CustomerId);

しかし、Customer で PrimaryAddress を設定するための正しいマッピングを指定するにはどうすればよいでしょうか? それとも間違ったアプローチですか?

ありがとう

編集 - Arnolds と LueTM の両方の回答を使用:

このコードは現在機能しています。

お客様:

public class Customer
{
    public int CustomerId { get; set;}
    public String CustomerName { get; set; }
    // public int PrimaryAddressId { get; set; } created in mapping
    public virtual CustomerAddress PrimaryAddress { get; set; }
    public virtual ICollection<CustomerAddress> CustomerAddresses { get; set; }    
}

住所:

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

顧客マッピング:

        modelBuilder.Entity<Customer>
            .HasOptional(c => c.PrimaryAddress)
            .WithOptionalDependent().Map(m => m.MapKey("PrimaryAddressId"));

        modelBuilder.Entity<Customer>
            .HasMany(c => c.CustomerAddresses)
            .WithRequired(c => c.Customer)
            .HasForeignKey(c => c.CustomerId)
            .WillCascadeOnDelete(false);

また、リポジトリを使用して、最初に新しいアドレスを作成して保存し、次にプライマリとして設定して再度保存するようにしています。リポジトリは、プライマリが「必須」であることを確認します。

4

1 に答える 1

1

例外が表示されないので、ニワトリが先か卵が先かという問題に遭遇したと思わざるを得ません。

PrimaryAddress必須プロパティとして設定する場合、EF には、外部キー (PrimaryAddressIdで設定Customer) を確立するための既存のアドレス ID が必要です。ただし、 がAddress必要なためCustomer、顧客の前にアドレスを保存することはできません。また、アドレスと顧客を 1 つのテイクで保存しようとすると、EF は挿入の正しい順序を判断できません。これは、EF が、他のオブジェクトの生成された ID を持つ両方のオブジェクトを挿入する必要があるためです。

したがって、AddressorCustomerにはオプションの外部キーが必要です。

オプションにしCustomer.PrimaryAddressIdます:

modelBuilder.Entity<Customer>().HasOptional(c => c.PrimaryAddress)
    .WithOptionalDependent();

これで、住所を保存し、別のトランザクションでプライマリ住所を顧客に割り当てることができます。Customerただし、 が常にプライマリ アドレスを持つようにするためのビジネス ロジックが必要です。

顧客とアドレスを 1 つのトランザクションで保存したい場合は、IsPrimaryプロパティ (ブール値) を追加しCustomerAddressて、常に 1 つのアドレスだけがtrue.

于 2012-10-21T10:23:28.357 に答える