【问题标题】:Use dictionary inside linq query在 linq 查询中使用字典
【发布时间】:2012-11-22 13:29:27
【问题描述】:

我想在我的 linq 查询中使用一些字典,但是由于 LINQ to entity 无法翻译字典的使用,它会引发异常。 实际上,以下问题中描述了相同的问题: linq to entity framework: use dictionary in query

我对那里描述的解决方案不满意。我确信这个问题还有其他解决方案。我不想使用 ToList/ToArray 方法 - 这会将所有数据带到内存中。

在不将数据库数据拉入内存的情况下,解决此问题的最佳方法是什么?

【问题讨论】:

  • 请显示您当前的 - 失败 - 代码
  • 我可能是错的,但我不相信你可以使用 Linq to Entities 使用字典而不先将数据拉到内存。
  • @DanielHilgarth 这是一个例子:Dictionary<int> dict = new Dictionary<int>(); dict.Add(1,1); dict.Add(2,2); var relatedEntities = (from e in Entities where dict.ContainsKey(e.id) select e); </int></int>

标签: linq dictionary linq-to-entities


【解决方案1】:

您的示例看起来您实际上不需要字典的功能,您只需要 WHERE IN 功能。
您可以使用以下方法来实现此目的:

var countries = Countries.WhereIn(x => x.CountryId, dict.Keys);

WhereIn 不是内置查询运算符,您需要自己编写 - 或复制:

/// <summary>
/// Holds extension methods that simplify querying.
/// </summary>
public static class QueryExtensions
{
    /// <summary>
    ///   Return the element that the specified property's value is contained in the specified values.
    /// </summary>
    /// <typeparam name="TElement"> The type of the element. </typeparam>
    /// <typeparam name="TValue"> The type of the values. </typeparam>
    /// <param name="source"> The source. </param>
    /// <param name="propertySelector"> The property to be tested. </param>
    /// <param name="values"> The accepted values of the property. </param>
    /// <returns> The accepted elements. </returns>
    public static IQueryable<TElement> WhereIn<TElement, TValue>(
        this IQueryable<TElement> source, 
        Expression<Func<TElement, TValue>> propertySelector, 
        params TValue[] values)
    {
        return source.Where(GetWhereInExpression(propertySelector, values));
    }

    /// <summary>
    ///   Return the element that the specified property's value is contained in the specified values.
    /// </summary>
    /// <typeparam name="TElement"> The type of the element. </typeparam>
    /// <typeparam name="TValue"> The type of the values. </typeparam>
    /// <param name="source"> The source. </param>
    /// <param name="propertySelector"> The property to be tested. </param>
    /// <param name="values"> The accepted values of the property. </param>
    /// <returns> The accepted elements. </returns>
    public static IQueryable<TElement> WhereIn<TElement, TValue>(
        this IQueryable<TElement> source, 
        Expression<Func<TElement, TValue>> propertySelector, 
        IEnumerable<TValue> values)
    {
        return source.Where(GetWhereInExpression(propertySelector, values.ToList()));
    }

    /// <summary>
    ///   Gets the expression for a "where in" condition.
    /// </summary>
    /// <typeparam name="TElement"> The type of the element. </typeparam>
    /// <typeparam name="TValue"> The type of the value. </typeparam>
    /// <param name="propertySelector"> The property selector. </param>
    /// <param name="values"> The values. </param>
    /// <returns> The expression. </returns>
    private static Expression<Func<TElement, bool>> GetWhereInExpression<TElement, TValue>(
        Expression<Func<TElement, TValue>> propertySelector, ICollection<TValue> values)
    {
        var p = propertySelector.Parameters.Single();
        if (!values.Any())
            return e => false;

        var equals =
            values.Select(
                value =>
                (Expression)Expression.Equal(propertySelector.Body, Expression.Constant(value, typeof(TValue))));
        var body = equals.Aggregate(Expression.OrElse);

        return Expression.Lambda<Func<TElement, bool>>(body, p);
    }
}

【讨论】:

猜你喜欢
  • 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
相关资源
最近更新 更多