如何解决C#AutoMapper与映射多对多错误外键有关的问题
我遇到了将模型映射到具有多对多关系的实体的奇怪问题
我有以下实体和模型:
using System;
using System.Diagnostics;
using System.Collections.Generic;
namespace AutoMapper.ReproducedExample
{
public class StoreEntity
{
public int Id { get; set; }
public string Name { get; set; }
public List<StoreProductEntity> Products { get; set; } = new List<StoreProductEntity>();
}
public class ProductEntity
{
public int Id { get; set; }
public string Name { get; set; }
public List<StoreProductEntity> Stores { get; set; } = new List<StoreProductEntity>();
}
public class StoreProductEntity
{
public int StoreId { get; set; }
public StoreEntity Store { get; set; }
public int ProductId { get; set; }
public ProductEntity Product { get; set; }
}
public class StoreModel
{
public int Id { get; set; }
public string Name { get; set; }
public List<ProductModel> Products { get; set; } = new List<ProductModel>();
}
public class ProductModel
{
public int Id { get; set; }
public string Name { get; set; }
public List<StoreModel> Stores { get; set; } = new List<StoreModel>();
}
public class CustomProfile : Profile
{
public CustomProfile()
{
CreateMap<StoreModel,StoreEntity>()
.ForMember(d => d.Products,opt => opt.MapFrom(s => s.Products))
.AfterMap((model,entity) =>
{
foreach (var entityProduct in entity.Products)
{
entityProduct.StoreId = entity.Id;
entityProduct.Store = entity;
}
});
CreateMap<StoreModel,StoreProductEntity>()
.ForMember(entity => entity.StoreId,opt => opt.MapFrom(model => model.Id))
.ForMember(entity => entity.Store,opt => opt.MapFrom(model => model))
.ForMember(entity => entity.ProductId,opt => opt.Ignore())
.ForMember(entity => entity.Product,opt => opt.Ignore());
CreateMap<ProductModel,ProductEntity>()
.ForMember(d => d.Stores,opt => opt.MapFrom(s => s.Stores))
.AfterMap((model,entity) =>
{
foreach (var entityStore in entity.Stores)
{
entityStore.ProductId = entity.Id;
entityStore.Product = entity;
}
});
CreateMap<ProductModel,opt => opt.Ignore())
.ForMember(entity => entity.Store,opt => opt.Ignore())
.ForMember(entity => entity.ProductId,opt => opt.MapFrom(model => model.Id))
.ForMember(entity => entity.Product,opt => opt.MapFrom(model => model));
}
}
class Program
{
static void Main(string[] args)
{
var configuration = new MapperConfiguration(cfg =>
{
cfg.AddProfile<CustomProfile>();
});
#if DEBUG
configuration.AssertConfigurationIsValid();
#endif
var mapper = configuration.CreateMapper();
var store0 = new StoreModel()
{
Id = 1,Name = "Store0",};
var store1 = new StoreModel()
{
Id = 2,Name = "Store1",};
var product = new ProductModel()
{
Id = 1,Name = "Product",};
store1.Products.Add(product);
product.Stores.Add(store1);
store0.Products.Add(product);
product.Stores.Add(store0);
var store0Entity = mapper.Map<StoreEntity>(store0);
Debug.Assert(store0Entity.Products[0].Product.Stores[0].Store.Id ==
store0Entity.Products[0].Product.Stores[0].Store.Products[0].StoreId);
}
}
}
映射成功,但是由于某种原因某些深键未映射到相关的StoreEntity
以下断言失败...
Debug.Assert(store0Entity.Products[0].Product.Stores[0].Store.Id ==
store0Entity.Products[0].Product.Stores[0].Store.Products[0].StoreId);
似乎由于某种原因在深度商店类AutoMapper中使用了错误的映射列表...但我不确定...
解决方法
我已经解决了这个问题(感谢问题Automapper creates 2 instances of one object的回答)
要检测Circular references
,我可以添加.PreserveReferences()
进行映射的方法
这里是正确的CustomProfile
:
public class CustomProfile : Profile
{
public CustomProfile()
{
CreateMap<StoreModel,StoreEntity>()
.ForMember(d => d.Products,opt => opt.MapFrom(s => s.Products))
.AfterMap((model,entity) =>
{
foreach (var entityProduct in entity.Products)
{
entityProduct.StoreId = entity.Id;
entityProduct.Store = entity;
}
})
.PreserveReferences();
CreateMap<StoreModel,StoreProductEntity>()
.ForMember(entity => entity.StoreId,opt => opt.MapFrom(model => model.Id))
.ForMember(entity => entity.Store,opt => opt.MapFrom(model => model))
.ForMember(entity => entity.ProductId,opt => opt.Ignore())
.ForMember(entity => entity.Product,opt => opt.Ignore());
CreateMap<ProductModel,ProductEntity>()
.ForMember(d => d.Stores,opt => opt.MapFrom(s => s.Stores))
.AfterMap((model,entity) =>
{
foreach (var entityStore in entity.Stores)
{
entityStore.ProductId = entity.Id;
entityStore.Product = entity;
}
})
.PreserveReferences();
CreateMap<ProductModel,opt => opt.Ignore())
.ForMember(entity => entity.Store,opt => opt.Ignore())
.ForMember(entity => entity.ProductId,opt => opt.MapFrom(model => model.Id))
.ForMember(entity => entity.Product,opt => opt.MapFrom(model => model));
}
}
但是实际上我不知道这是否是一个问题,因为根据文档,AutoMapper应该针对AutoMapper 10.0.0版自动检测Circular References,并且看来这是一个问题
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。