循环/反映所有EF模型中的所有属性以设置列类型 [英] Loop/reflect through all properties in all EF Models to set Column Type
问题描述
我的客户端具有存储具有十进制(13,4)规范的SQL Server小数的标准。因此,在一个非常大和仍在增长的模式中,我已经有近一百个这样的陈述:
My client has a standard of storing SQL Server decimals with a decimal(13,4) specification. As a result, in a very large and still-growing schema, I have nearly a hundred statements like these:
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)");
如果有一个功能,我可以直接告诉EF,所有的小数应该是小数(13,4 )默认情况下,我想使用它。如果没有,我可以使用反射来循环遍历模型中的每个对象/属性,以便我可以在几个语句中执行此操作吗?
If there is a feature where I can tell EF directly that all decimals should be decimal(13,4) by default, I would like to use that. If not, can I use reflection to loop through every object/property in the model so I can do this in a couple statements?
某些东西:
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)");
}
}
}
反思似乎是一个很好的方式因为那时我可以实现一些我们的其他约定,如果一个对象有一个名称和描述,则该名称是必需的,限制为256个字符。
Reflection seems like a great way to go, because then I can implement some of our other conventions where, if an object has a Name and Description, the Name is required and limited to 256 chars.
更新:
我按照Ivan的评论中的链接进行了修改,这对我有用:
Update: I followed the link in Ivan's comment and adapted it to this, which works for me:
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)";
}
不久之后,他提供了一个完整的答案,我稍微改变了工作十进制和可空的十进制:
Soon after, he provided a full answer, which I changed slightly to work with both decimal and nullable decimal:
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)");
}
两种方法都可以工作!
更新2:我必须在上下文中将我的对象声明为DbSet<>。当我逐行设置属性时,似乎不需要。
Update 2: I had to have my objects declared as DbSet<> in the context for the above to work. This didn't seem to be required when I was setting properties line by line.
推荐答案
在EF Core v1.1.0中,您可以使用这样的东西:
In EF Core v1.1.0 you can use something like this:
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)");
}
这篇关于循环/反映所有EF模型中的所有属性以设置列类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!