2

私はこのようなものを持っています:

public class HomeWork
{
    public DateTime Starts {get;set;}
    public DateTime Ends {get;set;}
}

そして、次のようなLINQクエリを作成したい:

var xxx = from hwrk in HomeWorks
    where hwrk.Starts.Between(date1, date2) || hwrk.Ends.Between(date1, date2) || 
        date1.Beetween(hwrk.Starts, hwrk.Ends) || date2.Between(hwrk.Starts, hwrk.Ends)
    select hwrk;

DateTime で動作する拡張機能を作成できますが、拡張機能が LINQ to SQL でも動作する必要があります。

内部で Where メソッドを使用している例をいくつか見つけましたが、それは IQueryable インターフェイスで動作します。しかし、個々のプロパティで機能する必要があります。一部の例では Expressions を使用していますが、そのようなことを行う例は見つかりません。

プロパティと通常の変数で機能し、LINQ to SQL でも機能する拡張機能の例を教えてください。または単にこれは私ができないことですか?

4

3 に答える 3

2

「Between 」式を返す関数を実装し、LinqKit の AsExpandableを利用して、再利用可能な式をラムダにプラグインできます。

ただし、かなり複雑になるため、この特定の状況で行うことはお勧めしません。手動で行う方が簡単だと思いますが、繰り返しになりますが、より簡単で維持しやすいでしょう。

そうは言っても、アプローチを確認できるように、式を使用して以下に実装しました。

最初のステップは、「between」式を返すメソッドを作成することです。インターフェイスを使用してこれを実装したIComparableので、これを同等の型に使用できます。

public static Expression<Func<TComparable, TComparable, TComparable, bool>> Between<TComparable>(this TComparable thisComparable) where TComparable : IComparable
{
    return (value, lower, upper) => lower.CompareTo(value) <= 0 && value.CompareTo(upper) <= 0;
}

その後、次のように使用できます。

var between = Extensions.Between<DateTime>();

AsExpandable式は、LinqKit のメソッドとInvokeメソッドを使用してクエリにプラグインできます。

var query = from m in context.Members.AsExpandable()
            where between.Invoke(m.CreatedDate, startDate, endDate)
            select m;

これにより、Linq to SQL を使用すると、次の SQL が生成されます。

-- Region Parameters
DECLARE @p0 DateTime = '2012-09-13 11:01:10.103'
DECLARE @p1 DateTime = '2012-09-20 11:01:10.103'
-- EndRegion
SELECT [t0].[MemberID], [t0].[Firstname], [t0].[Surname], [t0].[Email], [t0].[CreatedDate]
FROM [Member] AS [t0]
WHERE (@p0 <= [t0].[CreatedDate]) AND ([t0].[CreatedDate] <= @p1)
于 2012-09-20T10:14:54.287 に答える
0

インターフェイスの使用についてあなたが見つけたのIQueryableは、その方法です。その方法でやりたいことを行うことはできません.Linq to SQLプロバイダーがそれを理解できるように、式を取得して処理する必要があります.私が知っている唯一の方法は:

  • メソッドの「ダミー」実装をBetween拡張メソッドとして書くDateTime
  • の代わりに呼び出すIQueryable<T>拡張メソッド (たとえば) を記述し、同じ述語を渡します。ExpandWhere
  • 内部Expandでは、受け取った式ツリーを分析し、呼び出しが式とチェックにBetween変換される新しい式ツリーを生成する必要があります。これは、Linq to SQL が理解するものです。and<==>

あなたの問題がこの特定のケースだけにある場合は、Jon48が言ったことをします:)

于 2012-09-20T10:14:41.543 に答える
0

Linq2SQL の拡張に関する一般的な質問には直接答えないかもしれませんが、あなたの例から、時間枠内で開始または終了する宿題を探しています。ロジックに関しては、 を考えるとstart < end、これを単純化できます。

where hwrk.Starts <= date2 && hwrk.Ends >= date1
于 2012-09-20T09:57:49.870 に答える