【问题标题】:Use of "Single" in Dynamic Linq在 Dynamic Linq 中使用“Single”
【发布时间】:2011-06-18 12:14:30
【问题描述】:

我正在尝试将我在 Linq 中工作的 Linq 查询转换为能够在动态 linq 中工作(使用 System.Linq.Dynamic),因为我希望用户能够形成自己的查询和这个查询字符串将在运行时添加到其他查询字符串中。

我有一个问题:

db.incidents.Where(a => a.incidentLocations.Single().location.street.Contains(location);

我已尝试将其转换为以下动态 linq 字符串:

query = 
string.Concat("incidentLocations.Single().location.street.Contains(\"", location, "\")");

db.incidents.Where(query);

其中 location 是一个包含搜索文本的字符串。

我已设法将所有其他查询转换为动态 linq,但我正在努力解决异常错误:

“不存在适用的聚合方法‘Single’”

我知道动态 linq 不支持所有扩展方法,有人可以告诉我如何解决这个问题。

【问题讨论】:

  • 我没用过Dynamic Linq,你试过SingleOrDefault()吗?它或多或少做同样的事情。只有在没有找到记录而不是抛出错误时才返回null
  • 我对 Dynamic Linq 不是很熟悉,但是是 SQL 还是 Objects?
  • 也许单身应该是First()?
  • 既然可以将多个 linq 查询组合成一个巨大的表达式,为什么要将硬编码部分转换为动态的?保持原样,然后将额外的动态查询添加为额外的过滤器或子选择?

标签: linq


【解决方案1】:

很抱歉挖掘了一个很老的帖子,但我想我可以添加一些有价值的信息!

我必须使用 Linq to Entities 而不是 Linq to SQL 为 First()/FirstOrDefault() 执行此操作,我可以确认 @Guillaume86 的解决方案确实有效!

以下是我修改 MicrosoftDynamic.sql 的方法: 我在静态 DynamicQueryable 类中添加了这个:

    public static object FirstOrDefault(this IQueryable source)
        {
            if (source == null) throw new ArgumentNullException("source");
            return source.Provider.Execute(
                Expression.Call(
                    typeof(Queryable), "FirstOrDefault ",
                    new Type[] { source.ElementType },
                    source.Expression));
        }

我还将接口 IEnumerableSignatures 修改为

            void FirstOrDefault();

(我使用 FirstOrDefault 因为 First() 不是 linq 中对实体的最后一次调用时不支持)

您可以对任何支持的功能重复此操作:)

【讨论】:

  • 我很久以前就问过这个问题,但我现在将它设置为答案。
【解决方案2】:

获取 Linq.Dynamic 的源代码,复制粘贴 Where 方法,更改方法内部的签名和带有函数名称的字符串,就可以开始了。我这样做是为了添加 Single First 等,我无法在此处复制它,因为我不在我的开发机器上,但如有必要我会稍后再做;)

编辑:如果您决定使用 Single 方法:

public static object Single(this IQueryable source)
    {
        if (source == null) throw new ArgumentNullException("source");
        return source.Provider.Execute(
            Expression.Call(
                typeof(Queryable), "Single",
                new Type[] { source.ElementType },
                source.Expression));
    }

【讨论】:

  • 感谢您的回答,我考虑这样做,但我认为开始修改源代码比它的价值更麻烦。最后,我更改了 dbml 映射关系(其中相当复杂)以避免像 Manatherin 所说的那样使用 single()。
  • 虽然我无法验证您的答案现在是否有效,因为我已经以不同的方式解决了问题并且项目已经部署!感谢您不厌其烦地尝试解决我的问题。 (对不起,我没有足够的声望来支持你。)
  • 如果添加此方法,还需要将 Single 添加到 IEnumerableSignatures 接口(在同一文件中)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多