0

検索ボックスがあり、データを単語に分割しました。次に、これらの各単語をデータベース内のいくつかのフィールドと比較する必要があります。これが私が持っているコードです:

List<string> searchValues = searchString.Split(delimiters, StringSplitOptions.RemoveEmptyEntries).ToList();

using (DatabaseEntities context = new DatabaseEntities())
{
    IQueryable<DatabaseType> returnValue =
    context.DatabaseType.Where(y =>
        y.Field1.Contains(searchValues[0]) ||
        y.Field1.Contains(searchValues[0]));

    searchValues.Skip(1).ToList().ForEach(x =>
    {
        returnValue = returnValue.Where(y =>
            y.Field1.Contains(x) ||
            y.Field2.Contains(x));
    });

    return returnValue.ToList();

私の目標は、実際にアイテムをメモリにロードする前に、完全なクエリを作成することです。ただし、これを実行しようとすると、次のエラーが発生します。

System.NotSupportedException: LINQ to Entities does not recognize the method &#39;System.String get_Item(Int32)&#39; method, and this method cannot be translated into a store expression.

このタイプのエラーは、SQLへの変換で実行しようとしている操作が機能しないことを意味すると思っていましたが、以前は、ContainsをLIKEステートメントとして使用したことがあると確信しています。また、データベース内のすべての情報はnvarcharsであるため、これらは私のエンティティの文字列に相当します。誰かが問題が何であるかを知っていますか?これを行うには、IQueryableを使用するのが最善の方法ですか?可能であれば、これらすべてを遅延ロードすることをお勧めします。

4

2 に答える 2

2

get_Item(Int32)呼び出しは、リストへのインデックス付けになります。あなたの場合、それらはsearchValues[0]です。使用する:

var searchValue = searchValues[0];

IQueryable<DatabaseType> returnValue =
context.DatabaseType.Where(y =>
    y.Field1.Contains(searchValue) ||
    y.Field1.Contains(searchValue));
于 2012-10-08T01:44:26.173 に答える
0

以下の拡張メソッドを使用して、Linq to EntitiesのContains型式をビルドします(元のソースへの参照はコメントにあります)。このような状況でもうまくいくと思います。

    /// <summary>
    /// Extension method that enables .Contains(obj) like functionality for Linq to Entities.
    /// 
    /// Source: http://www.velocityreviews.com/forums/t645784-linq-where-clause.html
    /// </summary>
    /// <typeparam name="TElement">The element being evaluated by the Where clause</typeparam>
    /// <typeparam name="TValue">The value to match</typeparam>
    /// <param name="valueSelector">Lamda for selecting matching values</param>
    /// <param name="values">IEnumerable of the values</param>
    /// <returns>Expression consumable by Linq to Entities that reflects semantics of .Contains(value)</returns>
    /// <remarks>
    /// Usage:
    /// 
    /// Replace expression like 
    /// 
    /// where ChildrenIDs.Contains(items.CategoryID)
    /// 
    /// with
    /// 
    /// .Where((BuildContainsExpression<Item, int>(item => item.CategoryID, ChildrenIDs))
    /// 
    /// NOTE: If the item collection is large, the SQL query will be as well.
    /// </remarks>
    static public Expression<Func<TElement, bool>> BuildContainsExpression<TElement, TValue>(Expression<Func<TElement, TValue>> valueSelector, IEnumerable<TValue> values)
    {
        if (null == valueSelector)
        {
            throw new ArgumentNullException("valueSelector");
        }
        if (null == values) { throw new ArgumentNullException("values"); }

        ParameterExpression p = valueSelector.Parameters.Single();
        if (!values.Any())
        {
            return e => false;
        }

        var equals = values.Select(value => (Expression)Expression.Equal(valueSelector.Body, Expression.Constant(value, typeof(TValue))));
        var body = equals.Aggregate<Expression>((accumulate, equal) => Expression.Or(accumulate, equal));
        return Expression.Lambda<Func<TElement, bool>>(body, p);
    }

使用例:

var exprWithContains = 
    LinqToEntitiesUtil.BuildContainsExpression<List<int?>, int?>
        (p => p.ProductYear, productYears);

var result = (from p in products select p).Where(exprWithContains);
于 2012-10-08T01:37:31.990 に答える