如何使用 LINQ 和实体框架计算一行中所有列的校验和?

2024-02-15

我尝试执行的查询与此类似:

var checksum = from i in db.Items
    where i.Id == id
    select SqlFunctions.Checksum("*");

但是,这会返回字符串的校验和值"*"而不是评估通配符。有没有办法计算所有列的校验和?

Update:

var checksum = db.Database.SqlQuery<int?>("SELECT CHECKSUM(*) FROM [Catalog].[Item] WHERE Id = @p0", id);

这给了我想要的结果,但看起来很脏。有没有一种方法可以在不使用内联 SQL 的情况下做到这一点?


这可以通过SQL函数 https://msdn.microsoft.com/en-us/library/system.data.objects.sqlclient.sqlfunctions%28v=vs.110%29.aspx班级。该类允许 linq-to-entities 代码包含易于转换为 Sql 的方法。

首先,在您当前的编辑中:使用内联 SQL 并不“脏”,并且在大多数(如果不是全部)情况下完全没问题。 ORM 并不能提供一切,尤其是在不存在良好的对象列映射的情况下。然而,由于您使用的是实体框架,您可能还需要熟悉SqlFunctions https://msdn.microsoft.com/en-us/library/system.data.objects.sqlclient.sqlfunctions%28v=vs.110%29.aspx静态方法。

在这种情况下,有很多重载用于执行校验和,但它们必须都是同一类型。由于您没有发布您的列的类型或您有多少列,因此我不想在示例中推荐错误的重载供您使用。

以下是您的选择:

SqlFunctions.Checksum():

  • bool?
  • char[]
  • DateTime?
  • DateTimeOffset?
  • Decimal?
  • double?
  • Guid?
  • TimeSpan?
  • String

以上所有参数都有重载,最多允许 3 个参数(同一类型)。

SqlFunctions.AggregateChecksum():

  • IEnumerable<int>
  • IEnumerable<int?>

如果您查看这些函数的文档,您会发现您传递的参数是VALUES,而不是列名。所以你应该在一个Select()条款。这就是为什么当你通过时"*"对于该操作,它对包含单个星号而不是所有列的字符串进行校验和。另外,请记住,这些函数不能直接调用,只能在 Linq-To-Entities 查询中使用。

假设您的名为“ItemName”和“Description”的列都是字符串,并且您还需要您的 id,这是一个int:

var checksum = db.Items.Where(i => i.Id == id)
                       .Select(i => SqlFunctions.Checksum(i.Id.ToString(), i.ItemName, i.Description));

不幸的是,正如您在上面的示例中看到的,我们必须将 int 转换为字符串。没有允许使用不同类型的参数来计算校验和的重载,也没有任何选项允许在校验和函数中使用超过 3 个参数;然而,正如我上面提到的,有时您需要执行内联 SQL 命令,这是可以的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 LINQ 和实体框架计算一行中所有列的校验和? 的相关文章

随机推荐