4

使用实体框架 5

所以我有一个客户。客户可以有许多地址,但至少有一个。其中一个地址也将设置为主地址(必需)。我尝试了各种映射,但到目前为止,我在构建或为数据库播种时遇到错误。

顾客:

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

我的这部分映射工作正常。它在客户地址上。

        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 必须有一个现有的地址 Id 才能建立外键(PrimaryAddressId在 中设置Customer)。但是,由于Address需要Customer您不能在其客户之前存储地址。如果您尝试一次性保存一个地址和一个客户,EF 无法确定正确的插入顺序,因为它需要使用生成的另一个对象的 Id 插入两个对象。

所以要么AddressorCustomer必须有一个可选的外键。

我会Customer.PrimaryAddressId选择:

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

现在,您可以在单独的交易中存储地址并将主要地址分配给客户。但是您需要业务逻辑来确保 aCustomer始终具有主地址。

如果您想在一次交易中保存客户和地址,一种方法可能是添加一个IsPrimary属性(布尔)CustomerAddress并确保始终只有一个地址具有true.

于 2012-10-21T10:23:28.357 回答