正确配置多对一关系 ef core

Posted

技术标签:

【中文标题】正确配置多对一关系 ef core【英文标题】:Configuring Many-to-One relationship correctly ef core 【发布时间】:2021-12-29 16:44:39 【问题描述】:

我在我的项目中使用 CQRS 模式。我希望我的客户实体有可能拥有一组地址,因此我配置了一对多的 EF 关系。但是,当我创建一个新客户然后检索它时,地址字段只是一个空数组:


   "id": 1,
   "firstName": "string",
   "lastName": "string",
   "phone": "string",
   "email": "string",
   "primaryContact": "string",
   "secondaryContact": "string",
   "addresses": [],
   "orders": []

我对使用 AutoMapper 还很陌生,所以我想知道我是否没有正确配置关系

客户实体:

public class Customer : AuditableEntity

   public string FirstName  get; set; 
   public string LastName  get; set; 
   public string Phone  get; set; 
   public string Email  get; set; 
   public string PrimaryContact  get; set; 
   public string SecondaryContact  get; set; 

   #region Navigation Properties

   public virtual ICollection<Address> Addresses  get; set; 
   public virtual ICollection<Order> Orders  get; set; 

   #endregion

地址实体:

public class Address : AuditableEntity

   public string AddressLine1  get; set; 
   public string AddressLine2  get; set; 
   public string Region  get; set; 
   public string PostalCode  get; set; 
   public string Country  get; set; 

AddressDTO 只是地址实体中设置的属性,没有导航属性。

public class AddressCreateDto

   public string AddressLine1  get; set; 
   public string AddressLine2  get; set; 
   public string Region  get; set; 
   public string PostalCode  get; set; 
   public string Country  get; set; 

GetCustomerByIdResponse

public class GetCustomerByIdResponse

   public int Id  get; set; 
   public string FirstName  get; set; 
   public string LastName  get; set; 
   public string Phone  get; set; 
   public string Email  get; set; 
   public string PrimaryContact  get; set; 
   public string SecondaryContact  get; set; 
        
   public virtual ICollection<Address> Addresses  get; set; 
   public virtual ICollection<Order> Orders  get; set; 

我的 Auto Mapper 个人资料:

public AddressProfile()

   CreateMap<AddressCreateDto, Address>().ReverseMap();
   CreateMap<CreateCustomerCommand, Address>().ReverseMap();


public CustomerProfile()

   CreateMap<CreateCustomerCommand, Customer>().ReverseMap();
   CreateMap<GetCustomerByIdResponse, Customer>()
      .ForMember(dst => dst.Orders, opt => opt.MapFrom(src =>
                 src.Orders))
      .ReverseMap();

【问题讨论】:

您写道Customer 应该有Addresses 的数组,但是在您的代码中,客户只有一个地址,而地址有很多客户。 谢谢。我已将客户实体更改为拥有地址集合,并从地址中删除了客户集合。我删除了客户中地址集合的映射,因为我收到了一个异常:Error Mapping Types: CreateCustomerCommand -&gt; Customer Type Map configuration: CreateCustomerCommand -&gt; Customer CreateCustomerCommand -&gt; Customer Destination Member: Addresses。但是,我遇到的问题仍然存在。 docs.automapper.org/en/stable/Queryable-Extensions.html 【参考方案1】:

像您一样从预先编辑的帖子中修复关系后,我会检查并确保在使用 EF 检索 Customer 实体时,您使用的是

Include(x => x.Addresses)

所以看起来有点像这样(简化版)

var customers = Customers
    .Include(x => x.Addresses)
    .Include(x => x.Orders)
    .ToList();

否则 EF 核心不会从 db 中获取它们。 Orders 也是如此,它们需要单独的 Include 声明。

【讨论】:

这是一个因素,但主要问题是我没有分配集合值C# var customer = _mapper.Map&lt;Customer&gt;(request); var addressList = _mapper.Map&lt;List&lt;Address&gt;&gt;(request.Addresses); customer.Addresses = addressList;

以上是关于正确配置多对一关系 ef core的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate中一对多和多对一关系

如何正确映射与@IdClass 的多对一关系?

flask 定义数据关系(多对一)

MyBatis之多对一关系

Hibernate多表关系配置——多对一关系映射

Hibernate 多对一关联查询