ventajas tutorial net mvc modelo migraciones framework first existing exist español desventajas crear code asp entity-framework asp.net-core entity-framework-core

entity-framework - tutorial - net core entity framework existing database



Bucle/refleje a través de todas las propiedades en todos los modelos EF para establecer el tipo de columna (1)

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) || p.ClrType == typeof(decimal?)) .Select(p => modelBuilder.Entity(p.DeclaringEntityType.ClrType).Property(p.Name))) { pb.ForSqlServerHasColumnType("decimal(13,4)"); }

Actualización: a partir de EF Core 2.0, el modelo se HasAbcXyz por separado para cada proveedor de base de datos, por HasAbcXyz métodos HasAbcXyz se reemplazan con HasXyz común. El código actualizado (que también omite las propiedades configuradas explícitamente) se ve así:

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

Mi cliente tiene un estándar para almacenar 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 un centenar de declaraciones como estas:

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

Si hay una función en la que 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 declaraciones?

Algo como:

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

La reflexión parece un gran camino a seguir, 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 Ivan y lo adapté a esto, lo 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 decimales y decimales anulables:

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.