Linq查询中的表达式

本文关键字:表达式 查询 Linq | 更新日期: 2023-09-27 18:10:58

我最近发现我不能从linq查询中调用任何方法。我试图写一个查询,在哪里子句比较两个字节数组。数据库上的值是Raw(32)类型的GUID,它作为字节数组返回。这是该表的记录ID。我需要将它与另一个字节数组进行比较。第二个字节数组可以转换为字符串,但由于我不能从linq内调用方法,因此无法进行比较。

我绑定了一个自定义的"Compare"方法,我还编写了一个扩展方法。所有收到一个错误,指示"LINQ到实体不识别方法"

这是我想做的代码。where子句导致以下错误:LINQ到实体不能识别方法'Boolean SequenceEqual[Byte] (System.Collections.Generic)。IEnumerable 1[System.Byte], System.Collections.Generic.IEnumerable [System.Byte])'方法,该方法不能转换为存储表达式。"

EPSGEntities dbContex = new EPSGEntities();  
byte[] byteArray = ParseHex(ViewState["itemID"].ToString());
    var q = (from d in dbContex.EPSG_VSOREJECTS
              where d.SDSRECID.SequenceEqual(byteArray)
              select d).First();

Linq查询中的表达式

您使用的是哪个版本的EntityFramework ?在EF6上,我能够简单地对具有varbinary列的SQL 2012表执行以下操作:

var q = dbContext.EPSG_VSOREJECTS.FirstOrDefault(e => e.SDSRECID == byteArray);

EPSGEntities上的SDSRECID性质是byte[]型吗?

这里的替代方法是直接使用Sql来获取您的对象。比如:

dbContext.Database.SqlQuery<EPSG_VSOREJECT>("SELECT TOP 1 *" +
                                              "FROM dbo.EPSGEntities" +
                                              "WHERE SDSRECID = @byteString",
                                       new SqlParameter
                                       {    
                                         ParameterName = "byteString",
                                         Value = ViewState["itemID"].ToString(),
                                       }).FirstOrDefault();
对于大多数查询来说,EF中的Linq to Entities是很棒的,但是当我需要做一些不受支持的、复杂的或只是快速的事情时,我有时会使用sql。希望这对你有帮助!

我不完全确定这是否有效,但我发现在IQueryable对象集上调用.AsEnumerable()可以让我应用几乎任何我想要的代码:

var q = dbContex.EPSG_VSOREJECTS.
    .AsEnumerable()
    .Where(d => d.SDSRECID.SequenceEqual(byteArray));

这样做似乎阻止EF试图将Where()子句转换为SQL语法,但我不知道性能会受到什么影响。

这也是使用方法语法,因为我不太熟悉查询语法。HTH .

编辑:

正如其他一些人所指出的,您必须小心如何添加任何迭代方法(AsEnumerable(), ToList()等),因为在此之后,您不再针对数据存储构建SQL。一旦你开始迭代,EF将执行任何查询已经建立到那一点,从那时起,你从LINQ查询过滤结果集。

在这种情况下,我不知道这可以避免,除非有人可以建立相同的查询作为一个进程(EF可以代表你执行)。