我的客户端有一个存储SQL Server小数的标准,带有十进制(13,4)规范.结果,在一个非常大且仍在增长的模式中,我有近百个这样的语句:
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)");
Run Code Online (Sandbox Code Playgroud)
如果有一个功能,我可以直接告诉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)");
}
}
}
Run Code Online (Sandbox Code Playgroud)
反射似乎是一个很好的方法,因为那时我可以实现一些其他约定,如果一个对象有一个名称和描述,名称是必需的,并限制为256个字符.
更新: 我按照Ivan评论中的链接进行了调整,并对其进行了调整,这对我有用:
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)";
}
Run Code Online (Sandbox Code Playgroud)
不久之后,他提供了一个完整的答案,我稍微改了一下,使用十进制和可以为零的小数:
foreach (var pb in builder.Model
.GetEntityTypes() …Run Code Online (Sandbox Code Playgroud) 我一直试图弄清楚如何设置EF7(Beta 4)的小数精度没有运气.
我期待做类似的事情:
modelBuilder.Entity<SomeClass>().Property(p => p.DecimalProperty).Precision(10, 6)
Run Code Online (Sandbox Code Playgroud)
这似乎不可用,但我能够在GitHub的存储库中找到以下类:
没有使用RelationalTypeMapping类或方法签名的示例.也许这只是用作检索信息的映射api的一部分?
我可能期望的另一个地方是:
modelBuilder.Entity<SomeClass>().Property(p => p.DecimalProperty).ForRelational().ColumnType()
Run Code Online (Sandbox Code Playgroud)
要么
modelBuilder.Entity<SomeClass>().Property(p => p.DecimalProperty).ForSqlServer().ColumnType()
Run Code Online (Sandbox Code Playgroud)
这些只需要一个字符串,这个功能还没有实现,或者我只是没有找到正确的位置?
编辑:刚刚意识到字符串可能是.ColumnType("十进制(10,6)")类型的解决方案,直到进一步构建,仍然不介意得到一些澄清,因为我不希望使用字符串为此
编辑:在从bricelam澄清后,我最终创建了以下扩展以供使用,以避免使用字符串,我感谢他们的方法简单:
public static RelationalPropertyBuilder DecimalPrecision(this RelationalPropertyBuilder propertyBuilder, int precision, int scale)
{
return propertyBuilder.ColumnType($"decimal({precision},{scale})");
}
Run Code Online (Sandbox Code Playgroud)
用法示例:
modelBuilder.Entity<SomeClass>().Property(p => p.DecimalProperty).ForRelational().DecimalPrecision(10,6);
Run Code Online (Sandbox Code Playgroud)
编辑:对RC1进行修改
我还没有对它们进行过测试,但我只是将以下2个样本放在一起,这可能与RC1一样
public static PropertyBuilder DecimalPrecision(this PropertyBuilder propertyBuilder, string precision, string scale)
{
return propertyBuilder.HasColumnType($"decimal({precision},{scale})");
}
public static PropertyBuilder SqlDecimalPrecision(this PropertyBuilder propertyBuilder, string precision, string scale)
{
return propertyBuilder.ForSqlServerHasColumnType($"decimal({precision},{scale})");
}
Run Code Online (Sandbox Code Playgroud)
由于我还没有尝试过这个,我不确定"HasColumnType"或"ForSqlServerHasColumnType"之间的正确用法,但希望这会指向某个人正确的方向.
在 EF6 中,我可以使用以下代码,以便我的所有日期都使用 datetime2(0) 作为列类型
modelBuilder.Properties<DateTime>()
.Configure(c => c
.HasColumnType("datetime2")
.HasPrecision(0));
Run Code Online (Sandbox Code Playgroud)
我怎样才能在 EFCore 中做到这一点?
我的 c# 对象有一个小数属性:
public decimal LastPrice { get; set; }
Run Code Online (Sandbox Code Playgroud)
在处理我的对象时,设置了十进制值。例如:
LastPrice = 0.091354;
Run Code Online (Sandbox Code Playgroud)
我修改了 DbContext 以提高小数精度,如另一篇 stackoverflow 帖子中所述:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
foreach (var property in modelBuilder.Model.GetEntityTypes()
.SelectMany(t => t.GetProperties())
.Where(p => p.ClrType == typeof(decimal) || p.ClrType == typeof(decimal?)))
{
property.SetColumnType("decimal(38, 10)");
}
}
Run Code Online (Sandbox Code Playgroud)
Microsoft Sql Server Management Studio 中的表设计视图反映了此配置。这是从 SSMS 编写的表:
CREATE TABLE [dbo].[TradedCurrencyPairs](
[Id] [int] IDENTITY(1,1) NOT NULL,
[LastPrice] [decimal](38, 10) NOT NULL,
...
Run Code Online (Sandbox Code Playgroud)
当我在调试期间检查对象并将其添加到我的 DbContext 时,它看起来不错:

但在数据库中它最终为 0.0000000000。
据我所知,该值仍在四舍五入,就好像它的精度为 2 一样。本应为 0.09232 的值变成了 0.0900000000。所以所有小数仍然被削减。 …