0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

EntityFramework のエンティティをナビゲーションプロパティを除いてコピーする

Posted at

意味があるかどうかはわからないが、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.

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?