意味があるかどうかはわからないが、Contextからinclude付で取得したエンティティをナビゲーションプロパティを除いてコピーする方法。
ナビゲーションプロパティを無視するMapperを生成する
public static class MappingExtension
{
public static IMapper CreateMapperWithoutNavigation<TSource, TDestination>() => new MapperConfiguration(expression => {
expression.CreateMap<TSource, TDestination>()
.IgnoreNavigation();
}).CreateMapper();
public static AutoMapper.IMappingExpression<TSource, TDestination> IgnoreNavigation<TSource,TDestination>(this IMappingExpression<TSource, TDestination> expression)
{
var type = typeof(TDestination);
var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty);
foreach (var property in properties)
{
if (property.PropertyType.IsValueType)
{
continue;
}
if (property.PropertyType == typeof(string))
{
continue;
}
var nullable = property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>);
if (nullable)
{
var baseType = Nullable.GetUnderlyingType(property.PropertyType);
if (baseType.IsValueType)
{
continue;
}
if (baseType == typeof(string))
{
continue;
}
}
expression.ForMember(property.Name, x => x.Ignore());
}
return expression;
}
}
コピーを実行する
var mapper = MappingExtension.CreateMapperWithoutNavigation<Product, Product>();
using (var scope = serviceProvider.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<AdventureWorks.AdventureWorksDbContext>();
var products = await context.Products
.Include(x => x.ComponentBillOfMaterials)
.ThenInclude(x => x.ProductAssemblyProduct)
.Include(x => x.ProductAssemblyBillOfMaterials)
.ThenInclude(x => x.ProductAssemblyProduct)
.ToListAsync();
foreach(var product in products)
{
Console.WriteLine($"{product.Name}");
var copied = mapper.Map<Product>(product);
foreach (var component in copied.ComponentBillOfMaterials)
{
Console.WriteLine($"\t copied {component.ProductAssemblyProduct?.Name}");
}
foreach (var component in copied.ProductAssemblyBillOfMaterials)
{
Console.WriteLine($"\t copied {component.ProductAssemblyProduct?.Name}");
}
}
}
使ったデータベースは AdventureWorks2019、エンティティ生成は自前のT4.