C# 多重关系
使用实体框架5 所以我有一个顾客。客户可能有许多地址,但至少有一个。其中一个地址也将被设置为主地址(必需)。我尝试了各种映射,但到目前为止,我在构建时或在为数据库种子时遇到了一个错误 客户:C# 多重关系,c#,entity-framework,C#,Entity Framework,使用实体框架5 所以我有一个顾客。客户可能有许多地址,但至少有一个。其中一个地址也将被设置为主地址(必需)。我尝试了各种映射,但到目前为止,我在构建时或在为数据库种子时遇到了一个错误 客户: public class Customer { public int CustomerId { get; set;} public String CustomerName { get; set; } public int PrimaryAddressId { get; set; }
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 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; }
}
映射的这一部分工作正常。它在CustomerAddress上
this.HasRequired(c => c.Customer)
.WithMany(d => d.CustomerAddresses)
.HasForeignKey(c => c.CustomerId);
但是,如何指定在Customer中设置PrimaryAddress的正确映射?或者这是错误的方法
谢谢
编辑-使用Arnold和LueTM的答案:
此代码现在正在运行
客户:
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 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; }
}
客户映射:
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);
modelBuilder.Entity
.has可选(c=>c.PrimaryAddress)
.WithOptionalDependent().Map(m=>m.MapKey(“PrimaryAddressId”);
modelBuilder.Entity
.HasMany(c=>c.CustomerAddresses)
.WithRequired(c=>c.Customer)
.HasForeignKey(c=>c.CustomerId)
.WillCascadeOnDelete(假);
我使用存储库来确保首先创建并保存一个新地址,然后将其设置为主地址并再次保存。存储库确保主数据库是“必需的”。由于您没有显示异常,我不得不假设您遇到了一个鸡蛋问题 如果将
PrimaryAddress
设置为必需属性,则EF必须具有现有的地址Id才能建立外键(在Customer
中设置PrimaryAddressId
)。但是,由于地址
需要客户
,因此不能在其客户之前存储地址。如果您试图一次保存地址和客户,EF无法确定正确的插入顺序,因为它需要使用另一个对象的生成Id插入这两个对象
因此,地址
或客户
必须具有可选外键
我会将Customer.PrimaryAddressId
设置为可选:
modelBuilder.Entity<Customer>().HasOptional(c => c.PrimaryAddress)
.WithOptionalDependent();
modelBuilder.Entity().has可选(c=>c.PrimaryAddress)
.使用OptionalDependent();
现在,您可以在SeCreate事务中存储地址并为客户分配主地址。但您需要业务逻辑来确保客户始终具有主地址
如果您想在一个事务中保存客户和地址,一种方法可以是向客户地址添加IsPrimary
属性(bool),并确保始终只有一个地址true
请显示错误和出现错误的代码段。(通过编辑你的帖子)是的,这很有效。您是对的,尝试在一个事务中保存地址并将其分配为主地址。我想我太关注主地址“必需”了。总而言之:它现在生成自己的伪造密钥。我可以把它映射到我自己的“PrimaryAddressId”吗?也解决了这个问题。我删除了PrimaryAddress id,而是为它添加了一个映射:this.HasOptional(c=>c.PrimaryAddress).WithOptionalDependent().Map(m=>m.MapKey(“PrimaryAddressId”);啊,没有看到你的评论,但很高兴你找到了!