C# Linq到SQL会导致到数据库的脆弱耦合

C# Linq到SQL会导致到数据库的脆弱耦合,c#,sql-server,oop,linq-to-sql,C#,Sql Server,Oop,Linq To Sql,Linq to SQL正在截断十进制类型,而不是将其舍入。很明显,这是我的。为了避免这个问题,我在C代码中对值进行四舍五入。例如,假设我有: public class Foo { public decimal SomeNumber { get; set; } } SomeNumber的数据库类型为decimal(9,5)。这种精确性是客户做出的商业决策 如果代码中的SomeNumber是.00079547,则L2S在将查询发送到SQL Server时会将其截断为.00079。我需要做的

Linq to SQL正在截断十进制类型,而不是将其舍入。很明显,这是我的。为了避免这个问题,我在C代码中对值进行四舍五入。例如,假设我有:

public class Foo
{
    public decimal SomeNumber { get; set; }
}
SomeNumber的数据库类型为decimal(9,5)。这种精确性是客户做出的商业决策

如果代码中的SomeNumber是.00079547,则L2S在将查询发送到SQL Server时会将其截断为.00079。我需要做的是将数字四舍五入到.00080。为了做到这一点,我在代码中使用了以下方法:

private static decimal RoundToMatchSqlServerPrecision(decimal numberToRound)
{
    const int roundingPlaces = 5;

    return Math.Round(numberToRound, roundingPlaces);
}
如您所见,我现在有了与数据库中的类型紧密耦合的C#代码。如果我们更改数据库中的类型,我们必须记住更改此代码,这并不酷。我有两个问题:

  • 有更好的办法吗
  • 如果我必须将这种舍入逻辑放在代码中,那么将其放在业务逻辑层或数据访问层有意义吗
  • 1.有没有更好的办法

    恐怕不行。问题与
    SqlCommand
    s决定将参数化查询作为远程过程调用(RPC)执行有关。这意味着它执行一个
    sp_executesql
    命令,而不是直接的SQL命令(我从中得到了这个信息)

    我发现
    sp_executesql
    中的参数总是被截断(而不是四舍五入)到它们所关联的数据类型的精度。我不知道为什么,这似乎与在t-SQL中为十进制指定更高精度的值不一致,这会导致值被舍入:

    SET NUMERIC\u ROUNDABORT OFF--是默认值
    声明@p1十进制数(16,6)=32.6607647
    打印@p1
    --结果:32.660765
    
    因此,我认为除了自己做取整外,没有其他工作。(另一方面,.Net中的默认舍入方法是银行家舍入。您可能需要使用
    中点舍入.AwayFromZero


    2.业务逻辑层还是数据访问层

    在我看来,这与数据层实现密切相关(对于其他数据库供应商来说可能不是重点!),因此我不会让这种特性渗透到业务层。此外,在业务层中,您可能希望以最大精度保留中间计算结果。只有在存储值时,舍入才起作用

    1.有没有更好的办法

    恐怕不行。问题与
    SqlCommand
    s决定将参数化查询作为远程过程调用(RPC)执行有关。这意味着它执行一个
    sp_executesql
    命令,而不是直接的SQL命令(我从中得到了这个信息)

    我发现
    sp_executesql
    中的参数总是被截断(而不是四舍五入)到它们所关联的数据类型的精度。我不知道为什么,这似乎与在t-SQL中为十进制指定更高精度的值不一致,这会导致值被舍入:

    SET NUMERIC\u ROUNDABORT OFF--是默认值
    声明@p1十进制数(16,6)=32.6607647
    打印@p1
    --结果:32.660765
    
    因此,我认为除了自己做取整外,没有其他工作。(另一方面,.Net中的默认舍入方法是银行家舍入。您可能需要使用
    中点舍入.AwayFromZero


    2.业务逻辑层还是数据访问层


    在我看来,这与数据层实现密切相关(对于其他数据库供应商来说可能不是重点!),因此我不会让这种特性渗透到业务层。此外,在业务层中,您可能希望以最大精度保留中间计算结果。只有在存储值时,舍入才起作用。

    “这种精度是客户做出的一项业务决策。”也许这种重要的域行为不应由数据库负责?即使责任不应由数据库负责,我们仍然必须选择小数位数,然后在保存到DB时正确地取整。我想说的是,如果是域行为,则规则应该作为不变量编码到域模型中。这与数据库模式本身无关。您在问题的最后一句中暗示了这一点。这是否意味着您认为应该在业务逻辑类中对其进行四舍五入?“这种精度是客户做出的业务决策。”也许这样的话,这个重要的域行为不应该是数据库的责任?即使责任不应该在DB上,我们仍然必须选择要使用的小数位数,然后在保存到DB时正确地四舍五入。我想说的是,如果是域行为,该规则应作为不变量编码到域模型中。这与数据库模式本身无关。您在问题的最后一句中暗示了这一点。那么这是否意味着您认为它应该在业务逻辑类中四舍五入?+1我喜欢其他DB供应商可能没有这个问题的观点。我倾向于同意这种舍入属于数据层,但我的同事提出了不同的建议。这就是为什么我想了解别人的想法。谢谢+1我喜欢其他DB供应商可能没有这个问题的观点。我倾向于同意这种舍入属于数据层,但我的同事提出了不同的建议。这就是为什么我想了解别人的想法。谢谢