Realice un ciclo / refleje a través de todas las propiedades en todos los modelos EF para establecer el tipo de columna

Mi cliente tiene un estándar de almacenamiento de decimales de SQL Server con una especificación decimal (13,4). Como resultado, en un esquema muy grande y aún en crecimiento, tengo casi cien declaraciones como estas:

builder.Entity() .Property(x => x.MyField1) .ForSqlServerHasColumnType("decimal(13,4)"); builder.Entity() .Property(x => x.MyField2) .ForSqlServerHasColumnType("decimal(13,4)"); builder.Entity() .Property(x => x.MyField1) .ForSqlServerHasColumnType("decimal(13,4)"); 

Si hay una función donde puedo decirle a EF directamente que todos los decimales deben ser decimales (13,4) por defecto, me gustaría usar eso. Si no, ¿puedo usar la reflexión para recorrer cada objeto / propiedad en el modelo para poder hacer esto en un par de enunciados?

Algo como:

 foreach(var efObj in EntityFrameWorkObjects) { foreach (var objProperty in efObj) { if (objProperty is decimal || objProperty is decimal?) { builder.Entity() .Property(x => x.efObj) .ForSqlServerHasColumnType("decimal(13,4)"); } } } 

La reflexión parece una gran manera de hacerlo, porque entonces puedo implementar algunas de nuestras otras convenciones donde, si un objeto tiene un Nombre y una Descripción, el Nombre es obligatorio y está limitado a 256 caracteres.

Actualización: seguí el enlace en el comentario de Iván y lo adapté a esto, que funciona para mí:

 foreach (var p in builder.Model .GetEntityTypes() .SelectMany(t => t.GetProperties()) .Where(p => p.ClrType == typeof(decimal) || p.ClrType == typeof(decimal?))) { p.SqlServer().ColumnType = "decimal(13,4)"; } 

Poco después, proporcionó una respuesta completa, que cambié ligeramente para trabajar con decimal tanto decimal como nulo:

 foreach (var pb in builder.Model .GetEntityTypes() .SelectMany(t => t.GetProperties()) .Where(p => p.ClrType == typeof(decimal) || p.ClrType == typeof(decimal?)) .Select(p => builder.Entity(p.DeclaringEntityType.ClrType) .Property(p.Name))) { pb.ForSqlServerHasColumnType("decimal(13,4)"); } 

¡Ambos enfoques funcionan!

Actualización 2: tuve que declarar mis objetos como DbSet en el contexto para que funcione lo anterior. Esto no parecía ser necesario cuando estaba configurando propiedades línea por línea.

En EF Core v1.1.0 puedes usar algo como esto:

 foreach (var pb in modelBuilder.Model .GetEntityTypes() .SelectMany(t => t.GetProperties()) .Where(p => p.ClrType == typeof(decimal)) .Select(p => modelBuilder.Entity(p.DeclaringEntityType.ClrType).Property(p.Name))) { pb.ForSqlServerHasColumnType("decimal(13,4)"); }