【问题标题】:Expressions in Linq QueryLinq 查询中的表达式
【发布时间】:2013-04-26 15:53:53
【问题描述】:

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

我绑定了一个自定义的“比较”方法,我还写了一个扩展方法。全部收到错误提示“LINQ to Entities 无法识别该方法”

这是我正在尝试做的代码。 where 子句导致此错误: LINQ to Entities 无法识别方法 'Boolean SequenceEqual[Byte] (System.Collections.Generic.IEnumerable1[System.Byte], System.Collections.Generic.IEnumerable1[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();

【问题讨论】:

  • 能不能先从DB加载,然后在本地副本上做sequenceEqual比较?
  • 明确一点,你不能从linq to sql调用方法,你可以在linq到对象中调用
  • 我想避免将整个表存储到数据集/列表中,然后再进行查询。我希望从 linq 查询中得到一个结果
  • 我找到了stackoverflow.com/questions/12903138/…,但不知道如何在这里应用
  • Linq to Entities 无法运行 C# 代码。它需要能够将您的查询转换为 SQL 语句。所以你要么需要重构,要么创建一个新方法来返回一个执行你想要的表达式。

标签: c# linq linq-to-sql


【解决方案1】:

您使用的是什么版本的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。希望这会有所帮助!

【讨论】:

    【解决方案2】:

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

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

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

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

    编辑:

    正如其他人所指出的,您必须小心添加任何迭代方法(AsEnumerable()ToList() 等),因为在此之后,您不再针对数据存储构建 SQL。开始迭代后,EF 将执行到目前为止已构建的任何查询,然后您将过滤来自 LINQ 查询的结果集。

    在这种情况下,我不知道这可以避免,除非有人可以构建与存储过程相同的查询(EF 可以代表您执行)。

    【讨论】:

    • 如果您不确定自己在做什么,这样做非常危险。发生的情况是您强制执行查询,在.AsEnumerable() 调用之前检索所有内容,然后在内存中对其进行过滤。在某些情况下,这可能是做你想做的最简单和最好的方法,但在大多数情况下,将数据库表的全部内容选择到内存中并不是你想要做的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多