【问题标题】:EF Core: Can I Use `.HasConversion()` For A SQL Float To C# Decimal Conversion?EF Core:我可以使用 `.HasConversion()` 进行 SQL 浮点数到 C# 十进制的转换吗?
【发布时间】:2019-07-05 00:27:33
【问题描述】:

我有各种现有的 SQL 表,其中包含保留价格的 float 列,我需要将它们加载到 C# decimal 属性中

在阅读了.HasConversion().HasColumnType() 方法之后,我想我可以读到一个SQL 浮点数(EF Core 应该知道这是一个浮点数,因为.HasColumnType() 并且实习生将其转换为@987654327 @) 然后使用 .HasConversion() 方法将其转换为 C# 十进制;反之亦然。

是我误解了还是我误用了这些方法?


上下文OnModelCreating

entity.Property(e => e.Price) // <-- decimal field
    .IsRequired()
    .HasColumnName("PREFIX-Price")
    .HasColumnType("float")
    .HasDefaultValueSql("((0))")
    .HasConversion(
        v => Decimal.ToDouble(v),
        v => Convert.ToDecimal(v)
    )

运行类似的东西后:

var x = myContext.TableName.Select(x => x.Price);

我得到以下异常:

InvalidCastException: Unable to cast object of type 'System.Double' to type 'System.Decimal'.
System.Data.SqlClient.SqlBuffer.get_Decimal()
System.Data.SqlClient.SqlDataReader.GetDecimal(int i)
lambda_method(Closure , DbDataReader )
Microsoft.EntityFrameworkCore.Storage.Internal.TypedRelationalValueBufferFactory.Create(DbDataReader dataReader)

我不希望它调用 System.Data.SqlClient.SqlBuffer.get_Decimal() 而是获取浮点数/双精度数。

最后,我可以做我想做的事吗?


额外信息:

(虽然很明显)如果我要调用下面的代码,那么它可以正常工作,但这并不可行,因为我/其他人可能会忘记或没有意识到,再加上工作量!

var x = myContext.TableName.Select(x => Convert.ToDecimal(x.Price));

【问题讨论】:

  • 数据库迁移不是一种选择吗?就我个人而言,我会将 SQL 数据迁移到正确的数据类型,然后构建模型以匹配正确的状态。不这样做会导致副作用。
  • 很遗憾,80-90% 的网站都托管在经典的 asp 中(真正的老派!)。我在一张只在几页中使用过的小桌子上尝试过它,它有一些……副作用。旧经典 asp 中的每个字段实例都必须包含在 CDBL() 中。我试图让他们迁移到 NET CORE,但他们希望保留已自定义添加到站点的所有后端功能。
  • 您是否查看过 EF Core 中的值转换文档? docs.microsoft.com/en-us/ef/core/modeling/value-conversions
  • 请注意,尽管您要做的事情是可能的,但在写入数据库时​​会出现精度损失。 (我知道这很明显,但我觉得我还是应该说)
  • 另请注意,没有内置的浮点到十进制转换器,因此您必须定义一个。

标签: c# sql-server asp.net-core entity-framework-core


【解决方案1】:

您需要像这样创建自己的值转换器:

var converter = new ValueConverter<decimal, double>(
    v => (double)v,
    v => (decimal)v
);

然后在fluent API配置中使用:

modelBuilder
    .Entity<EntityType>()
    .Property(e => e.FeildName)
    .HasConversion(converter);

【讨论】:

  • 完全试过你的代码。对不起,没用。虽然它可能是 float to decimal 转换和我做 double to decimal,但没有运气
  • 对不起,我的错误,用双倍试试。我刚刚创建了一个控制台应用程序来重现这一点,并且我设法将它转换得很好,所以如果你希望我向你发送 repo,我可以。我已经更新了答案以反映正确的类型。
  • 我只是尝试将其更改为小数,并将其从内联实体模型(如我的)移到链式调用(如你的),但仍然没有运气。如果你可以发送回购,请。一个快速的问题是您的e.FieldName 是十进制属性吗?只是想确保我的财产是public decimal Price { get; set; }
  • 是的,FeildName 是十进制类型,它映射到的 SQL 模式是浮点类型。
  • 抱歉,我花了这么长时间,演示在我的工作笔记本电脑上。 gitlab.com/KieranDevvs/efvalueconversiontest希望有帮助。
猜你喜欢
  • 2021-09-10
  • 1970-01-01
  • 2014-03-01
  • 2015-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-24
  • 2011-08-11
相关资源
最近更新 更多