首先在实体框架模型中使用货币类型

Posted

技术标签:

【中文标题】首先在实体框架模型中使用货币类型【英文标题】:Use money type in Entity Framework model first 【发布时间】:2011-09-16 16:47:01 【问题描述】:

我创建了一个表,其中包含一个名为 Amount 的列,并将其设置为 Decimal。我找不到在哪里将其设置为 money 或 smallmoney,当我尝试设置像 0.2 这样的值时,它会四舍五入为 0....

如何在实体框架中使用金钱?

谢谢!

【问题讨论】:

【参考方案1】:

我的回答是关于 E.F 6.0 处理类似问题并使用 SQL Profiler 检查后: 实体框架在 SQL 中将 Decimal 变量类型转换为 Decimal(18, 2)。

如果你想省钱类型,我建议使用数据注释并添加

public class Account

    public int AccountId  get; set;                 

    [Column(TypeName="money")]
    public decimal Amount  get; set; 

或者如果你使用 Fluent API

protected override void OnModelCreating(ModelBuilder modelBuilder)

    modelBuilder.Entity<Account>()
                .Property(i => i.Amount)
                .HasColumnType("money");

Money 类型将转换为 (19, 4)

【讨论】:

这个解决方案对我很有效。需要注意的一件事:如果您处理的是小数金额(即 5.0125),则必须使用上面的数据注释,否则金额将四舍五入到小数点后 2 位。在我的特殊情况下,我不希望这种情况发生。【参考方案2】:

Entity Framework 的一个令人讨厌的地方是它在 SQL 中将 Decimal 变量类型转换为 Decimal(18, 0)。

逗号后面的数字是数字允许的小数位数。所以 Decimal(18,0) 保存时会去掉小数点后的数字。

转到 SQL Server Management stuido,找到您的数据库,右键单击表并选择“设计”。然后从列表中选择列,您只需在框中键入即可将数据类型更改为 Decimal(18, 2)。然后将更改保存到表中。然后它将数字保存到西方货币交易中通常使用的小数点后两位。如果您需要更多小数位,只需相应增加括号内的第二个数字即可。

我从未找到更改此 EF 默认值以便生成 Decimal(18, 2) 的设置。但后来我从来没有看过:在数据库中更改很容易。但如果有人知道,我很想知道它是如何完成的。

编辑:更多信息 - 包括配置修复 - 在这个答案中: Decimal precision and scale in EF Code First

【讨论】:

嗯,我没有使用 EF 6/6.1 的这种经验,我所有的小数都保存在 (18,2) 中 我无法评论 EF6(未使用它),但我确信我记得早期版本中发生过这种情况。我想可能是笨拙的实现 - 会在网上挖掘一下。 繁荣:***.com/questions/3504660/… 请注意,考虑到全球软件,2 位小数对于货币来说并不总是足够的。【参考方案3】:

所以我认为您的问题可能是代码优先方法。另外,我不确定您使用的是什么版本的 SQL,我下面的答案仅适用于 SQL Server。但是对于 Oracle 或 mysql,您基本上会以相同的方式进行操作。

模型优先:

使用 SQL Server,您只需为字段选择“money”或“smallmoney”,具体取决于您需要表示的值有多大。

代码优先:

我需要表达一种最高为 9999.99 的货币类型

在可视化 EDMX 编辑器中,您将选择标量属性,转到属性,然后将其设置为 Type = Decimal,然后将 Facets 设置为 Precision = 6 Scale = 2。您可以使用 Data Annotations 确保该字段显示并输入为钱。

【讨论】:

【参考方案4】:

这类似于Decimal precision and scale in EF Code First .我首先使用 EF 6.1 和代码,由于某种原因,默认事件将 smallmoney 定义为精度 2,尽管它是/应该是 4。您需要添加一些 Fluent 代码来解决这个问题。 我使用类似的东西:

public static void OnModelCreating(DbModelBuilder modelBuilder)

        modelBuilder.Entity<MYCLASSNAME>().Property(x => x.MYPROPNAME).HasPrecision(5+4, 4);

【讨论】:

以上是关于首先在实体框架模型中使用货币类型的主要内容,如果未能解决你的问题,请参考以下文章

如何在实体框架模型中使用通用导航属性?

如何使用无键实体类型在 EF 模型中定义查询?

首先在实体框架代码中使用搜索字符串搜索 DateTime

首先在实体框架模型中关闭跟踪

实体框架代码首先使用现有数据库

如何自定义与 EDMX(模型优先)实体框架 4.1 一起使用的表名?