3

次のようなコードを書きたい -

    public IQueryable<Invoice> InvoiceFilterForMonthAndYear(DateTime? monthAndYear = null)
    {
        var invoices = _invoices.Where(MonthAndYearPredicate(monthAndYear);
        return invoices;
    }

    private bool MonthAndYearPredicate(Invoice invoice, DateTime? monthAndYear)
    {
        //code to check if the invoice start or end dates is from the falls in the month I am checking for
    }

しかし、述語は 1 つのパラメーターしか想定していないため、そのような述語を使用することはできません。

作業を行うために Where 句を記述できることはわかってInvoiceFilterForMonthAndYearいますが、比較のロジックを独自のメソッドに入れたいと考えています。

4

2 に答える 2

5

比較用のメソッドが式を返す場合に機能します。

private Expression<Func<Invoice,bool>> MonthAndYearPredicate(
    DateTime? monthAndYear)
{
    return i => i.StartDate >= monthAndYear; // or whatever
}

あなたの例のように呼び出されるには:

var invoices = _invoices.Where(MonthAndYearPredicate(monthAndYear));

または、ロジックを次の拡張メソッドに抽出できますIQueryable<Invoice>

public static class QueryExtensions
{
    public static IQueryable<Invoice> WhereMonthAndYear(
        this IQueryable<Invoice> query, DateTime? monthAndYear)
    {
        return query.Where(i => i.StartDate >= monthAndYear); // or whatever
    }
}

次のように呼び出されます。

var invoices = _invoices.WhereMonthAndYear(monthAndYear);

どちらの場合も、EF が SQL に変換できる有効な LINQ-to-Entities 式を使用する必要があることに注意してください。異なるクエリで式を再利用できるようにするだけで、その機能を拡張することはありません。

于 2013-09-23T21:08:02.053 に答える
-1

ロジックをメソッドに抽出することはできません。その場合、メソッド呼び出しから生成される式ツリーには、クエリ プロバイダーがクエリを生成するための十分な情報が含まれません。すべてが最終的に式ツリーになるように、ロジックをインライン化する必要があります。

于 2013-09-23T19:40:48.027 に答える