1

データベースからデータを返すクエリを作成しています。フィルタリングしたいIDのリストを渡しています。フィルター リストが null または空の場合、すべてのものを返したいと思います。

これを可能にする拡張メソッドがあります。これ queryは、IQueryablenullIds許容 int のリストです (聞かないでください!)ListHasElementsは、リストが null ではなく、何かが含まれている場合に true を返すメソッドです。

 var filteredList = query.WhereIf(ListHasElements(Ids), s => Ids.Contains(s.Id.Value));

ただし、ビルドするときqueryは、好みのクエリ構文を使用します

var query = from a in dbContext.as
            join b in dbContext.bs on a.Id.ToString() equals b.Id
            join cin dbContext.cs on b.Id equals c.Id into bcJoin
            from items in bcJoin.DefaultIfEmpty()
            where b.Sent >= fromDate
            where b.Sent <= toDate
            select new{a=a.thing, b=b.thingy, q=items.q,Id=a.Id}

次に、魔法の WhereIf フィルターを実行するために最初の行を挿入する必要があります。最後に、さらにグループ化して出力オブジェクトを作成することを選択します (コードは示されていません!)

拡張方法はこんな感じ。

public static IQueryable<TSource> WhereIf<TSource>(this IQueryable<TSource> source, bool condition,
    Expression<Func<TSource, bool>> predicate)
{
    return condition ? source.Where(predicate) : source;
}

このメソッドをクエリ構文クエリで直接使用できますか?

4

3 に答える 3

1

MSDNからの引用:

一部のクエリは、メソッド呼び出しとして表現する必要があります

これはそれらのケースの 1 つです。独自の拡張メソッドの一部でさえ、メソッド構文を介して呼び出す必要があります。たとえば、Count.

于 2015-11-03T17:16:39.780 に答える
0

できません。コンパイラは、既知のクエリ構文キーワードを取得し、バックグラウンドでメソッド構文に変換します。カスタム拡張については何も知らないため、クエリ構文に同等のものはありません。他の「組み込み」linq 関数には、同等のクエリ構文がないことに注意してください。

  • Skip
  • Count
  • Take
  • Single
  • FirstOrDefault
  • Max

あなたの拡張機能は基本的に同等であることに注意してください

where !condition || predicate(b)
于 2015-11-03T17:17:54.737 に答える
-1

はい!

var query = from a in dbContext.as.WhereIf(ListHasElements(Ids), s => Ids.Contains(s.Id.Value))
        join b in dbContext.bs on a.Id.ToString() equals b.Id
        join cin dbContext.cs on b.Id equals c.Id into bcJoin
        from items in bcJoin.DefaultIfEmpty()
        where b.Sent >= fromDate
        where b.Sent <= toDate
        select new{a=a.thing, b=b.thingy, q=items.q,Id=a.Id}

私のテスト コード (Listings は Id フィールドを持つテーブルです):

void Main()
{
   var list=new int []{1,2,3,4};
   var query=from l in Listings.WhereIf(ListHasElements(list),s=>list.Contains(s.Id))
   select l;
   query.Dump();
}
public bool ListHasElements<T>(IEnumerable<T> it)
{
    return it.Any();
}

public static class Ext {
    public static IQueryable<TSource> WhereIf<TSource>(this IQueryable<TSource> source, bool condition,
        Expression<Func<TSource, bool>> predicate)
    {
        return condition ? source.Where(predicate) : source;
    }
}
于 2015-11-03T18:18:48.400 に答える