3

次の拡張メソッドがあります。

public static bool Between(this DateTime target, DateTime startDate, DateTime endDate)
{
    return target >= startDate && target <= endDate;
}

私はそれをこのように呼ぶことができます

if (expectedDate.Between(minDate, maxDate)) { do code }

私は今、これを次のようなLinq/Lambda式で使用しようとしています。

    return list.Where(item => targetDate.Between(item.StartDate, item.EndDate));
OR  if (!list.Any(pp => targetDate.Between(pp.StartDate, pp.EndDate)))

実行時に次のエラーが発生します。

LINQ to Entitiesは、メソッド'Boolean Between(System.DateTime、System.DateTime、System.DateTime)'メソッドを認識せず、このメソッドをストア式に変換できません。

しかし、これは問題ありません

if (!list.Any(item => targetDate >= item.StartDate && quoteDate.EventDate <=item.EndDate)))

呼び出す共通のメソッドが欲しいのですが。私のオプションは何ですか?

4

3 に答える 3

4

を必要としないブライアンのソリューションの簡単な変更AsExpandable()

public static IQueryable<TSource> Between<TSource, TKey>(
    this IQueryable<TSource> source, TKey key,
    Expression<Func<TSource, TKey>> lowSelector,
    Expression<Func<TSource, TKey>> highSelector)
    where TKey : IComparable<TKey>
{
    Expression low = lowSelector.Body;
    Expression high = highSelector.Body;

    Expression lowerBound = Expression.LessThanOrEqual(
        low, Expression.Constant(key));
    Expression upperBound = Expression.LessThanOrEqual(
        Expression.Constant(key), high);

    var lowLambda = Expression.Lambda<Func<TSource, bool>>(
        lowerBound, lowSelector.Parameters);
    var highLambda = Expression.Lambda<Func<TSource, bool>>(
        upperBound, highSelector.Parameters);

    return source.Where(lowLambda).Where(highLambda);
}
于 2011-11-18T10:20:00.600 に答える
3

LINQ to Objectを使用していないため、クエリは実行されませんが、 SQLに変換される式ツリーに変換されます。
LINQ to Entitiesは、作成したメソッドを実装してからSQLに変換する方法を認識していません。
LINQ to Entitiesを使用したことはありませんが、式ツリービルダーを拡張して、LINQ to EntitiesでメソッドをSQLに変換できるようにする方法が必要です。LINQtoNHibernateには、その方法があります。LINQをエンティティプロバイダーに拡張する方法の例を次に示します

于 2011-11-16T22:43:13.877 に答える
1

いくつかの異なる方法を使用して動作させました。オペレーター間のLINQから構築する新しいメソッドを作成しました

public static IQueryable<TSource> Between<TSource, TKey>(this IQueryable<TSource> source, TKey key, Expression<Func<TSource, TKey>> lowSelector, Expression<Func<TSource, TKey>> highSelector)
    where TKey : IComparable<TKey>
{
    Expression low = Expression.Invoke(lowSelector, lowSelector.Parameters.ToArray());
    Expression high = Expression.Invoke(highSelector, highSelector.Parameters.ToArray());

    Expression lowerBound = Expression.LessThanOrEqual(low, Expression.Constant(key));
    Expression upperBound = Expression.LessThanOrEqual(Expression.Constant(key),  high);

    Expression<Func<TSource, bool>> lambda = Expression.Lambda<Func<TSource, bool>>(lowerBound, lowSelector.Parameters);
    Expression<Func<TSource, bool>> lambda2 = Expression.Lambda<Func<TSource, bool>>(upperBound, highSelector.Parameters);
    return source.AsExpandable().Where(lambda).Where(lambda2);
}

AsExpandableまたはToList()を使用しない限り、これは機能しませんでした。

AsExpandable()はLinkKitからのものです

ToList()は、LinqtoエンティティからLinqTo Objectsに強制しますが、SQLを実行します。

あなたの助けと提案をありがとう

于 2011-11-17T18:24:57.583 に答える