6

文字列配列を反復処理して動的にクエリを作成しようとしていIQueryableます。その非常に簡単ですが、ここで私は立ち往生しています

var query = context.QuestionsMetaDatas.AsQueryable();

var keywords=new List<string>(){ "Test1","Test2" };

foreach(var key in keywords)
{
   query=query.Where(a=>a.Text.Contains(key));
}

問題は、クエリが生成されると、コンパイルが

select * from QuestionsMetaDatas where Text Like "Test1" AND Text Like "Test2"

ANDクエリを生成する代わりにOR...どうすればこれを達成できますか?

4

3 に答える 3

6

Raphael が提案したような述語ビルダーを使用しました。プロジェクトに含めるファイルは 1 つだけです。例は次のようになります。

var keywords=new List<string>(){ "Test1","Test2" };

var predicate = PredicateBuilder.False<QuestionsMetaDatas>();

foreach (var key in keywords)
{
  predicate = predicate.Or (a => a.Text.Contains (key));
}

var query = context.QuestionsMetaDatas.AsQueryable().Where(predicate);

探している OR クエリを生成します。

于 2013-09-12T20:32:16.237 に答える
5

他の方法で含まれていることを試しましたか?

var keywords=new List<int>(){ "Test1","Test2" };
query=query.Where(a=>keywords.Contains(a));

これはIN条項のようなものです

于 2013-09-12T12:23:50.210 に答える
2

述語ビルダーを見るか、独自の式を作成できます(ここでは、静的拡張メソッドを使用した可能な解決策ですIQueryable<QuestionsMetadatas>

public static IQueryable<QuestionsMetaDatas> FilterText(this IQueryable<QuestionsMetaDatas> queryable, IEnumerable<string> keywords)
        {
            var entityType = typeof(QuestionsMetaDatas);
            var parameter = Expression.Parameter(entityType, "a");
            var containsMethod = typeof(string).GetMethod("Contains"
                                                           , new[] { typeof(string) });
            var propertyExpression = Expression.Property(parameter, "Text");
            Expression body = Expression.Constant(false);
            foreach (var keyword in keywords)
            {
                var innerExpression = Expression.Call(propertyExpression, containsMethod, Expression.Constant(keyword));
                body = Expression.OrElse(body, innerExpression);
            }
            var lambda = Expression.Lambda<Func<QuestionsMetaDatas, bool>>(body, new[] { parameter });
            return queryable.Where(lambda);

        }

どこlambdaがそのようになります:

a => ((False OrElse a.Text.Contains("firstKeyWord")) OrElse a.Text.Contains("secondKeyWord"))

そして使い方は

var query = context.QuestionsMetaDatas.AsQueryable();

var keywords=new List<string>(){ "Test1","Test2" };

query = query.FilterText(keywords);

またはそれより短い

var query = context.QuestionsMetaDatas.AsQueryable().FilterText(new[]{"Test1", "Test2"});
于 2013-09-12T15:19:41.590 に答える