C# 如何使用LINQ和实体框架计算行中所有列的校验和?
我尝试执行的查询与此类似:C# 如何使用LINQ和实体框架计算行中所有列的校验和?,c#,sql-server,linq,entity-framework,linq-to-entities,C#,Sql Server,Linq,Entity Framework,Linq To Entities,我尝试执行的查询与此类似: var checksum = from i in db.Items where i.Id == id select SqlFunctions.Checksum("*"); 但是,这将返回字符串“*”的校验和值,而不是计算通配符。有没有办法计算所有列的校验和 更新: var checksum = db.Database.SqlQuery<int?>("SELECT CHECKSUM(*) FROM [Catalog].[Item] WHER
var checksum = from i in db.Items
where i.Id == id
select SqlFunctions.Checksum("*");
但是,这将返回字符串“*”
的校验和值,而不是计算通配符。有没有办法计算所有列的校验和
更新:
var checksum = db.Database.SqlQuery<int?>("SELECT CHECKSUM(*) FROM [Catalog].[Item] WHERE Id = @p0", id);
var checksum=db.Database.SqlQuery(“从[Catalog].[Item]中选择checksum(*),其中Id=@p0”,Id);
这给了我想要的结果,但看起来很肮脏。有没有一种方法可以在没有内联SQL的情况下实现这一点?这可以通过类来实现。该类允许linq到实体代码包含易于转换为Sql的方法
首先,在您当前的编辑中:使用内联SQL不是“脏”的,并且在大多数(如果不是所有)情况下完全可以。ORM并不能提供一切,尤其是在没有良好的对象列映射的情况下。然而,由于您使用的是实体框架,所以您也可以使用静态方法
在这种情况下,有很多重载用于执行校验和,但是它们必须是相同类型的。由于您没有发布您的列的类型或数量,我不想在示例中推荐错误的重载供您使用
以下是您的选择:
SqlFunctions.Checksum()
:
bool?
char[]
DateTime?
DateTimeOffset?
Decimal?
double?
Guid?
TimeSpan?
String
SqlFunctions.AggregateChecksum()
:
IEnumerable
IEnumerable
Select()
子句中使用它们。这就是为什么当您将“*”
传递给操作时,它会对包含单个星号而不是所有列的字符串进行校验和。另外,请记住,这些函数不能直接调用,只能在Linq To Entities查询中使用
假设名为“ItemName”和“Description”的列都是字符串,您还需要id,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命令,这没问题。您是否尝试过:sqlfunctions.checksumggregate(I.select(x=>x.Id));我没有选择的方法。此外,我还需要计算所有列的校验和,而不仅仅是Id。为什么需要计算所有列的校验和?我需要测试两个独立数据库中两个相同表上的行的相等性。这些表保证始终具有相同的架构。这是我想到的最简单的方法。为什么不把所有列上的两个表连接起来呢?这些列的类型不同,所以这些重载在这种情况下不会有用。我认为SQL看起来很脏,因为它是项目中唯一的SQL,并且当前位于我的控制器中,因为我的实体是首先生成的。我想我可以把它移到模型中的一个部分文件中,以摆脱我的口臭。@Jason如果你真的不喜欢在项目中使用SQL代码,你可以编写一个用户定义的函数或存储的过程。EF对这些特性的支持不是很强大,但它确实存在,可以在linq查询中使用。但是,请记住,ER是ORM,而不是SQL的替代品。有时,您只需要以老式的方式编写sql查询。