我的客户机有一个存储带有decimal(13,4)规范的sql server小数的标准。因此,在一个非常大且仍在增长的模式中,我有将近100个这样的语句:
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),我想使用它。如果不是,我可以使用反射循环遍历模型中的每个对象/属性,这样我就可以在两个语句中完成这项工作吗?
类似于:
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个字符。
更新:
我遵循了伊凡评论中的链接,并将其改编为适合我的:
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)";
}
不久之后,他给出了一个完整的答案,我稍微修改了一下,同时使用了decimal和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<>,才能工作。当我逐行设置属性时,这似乎不是必需的。