2

LINQ to Entitiesを使用して、PersonTableからレコードを取得する必要があります。ここでAgeはAgesFromとAgesToの間にあります。問題は、データベースに保存されているDateOfBirthと特定のDateToCalculateからAgeを計算する必要があることです。

例えば。PersonTable:DateOfBirth = 01/04/1972、DateToCalculateAge = 25/12/2011

.Where(0 < o.FormDate.AddYears(-agesFrom).CompareTo(o.FormDate.Subtract(o.Person.DateOfBirth)) &&
       0 > o.FormDate.AddYears(-agesTo).CompareTo(o.FormDate.Subtract(o.Person.DateOfBirth));
// ----------------------- OR ------------------------
.Where(agesFrom <= CalculateAge(o.Person.DateOfBirth.Value, o.FormDate) &&
       agesTo >= CalculateAge(o.Person.DateOfBirth.Value, o.FormDate);

提供されたコードに対して、次の例外が発生します。「LINQ to Entitiesは、メソッド'System.DateTime AddYears(Int32)'メソッドを認識せず、このメソッドをストア式に変換できません。」

LINQがクエリをデータベースに渡すと、使用しようとしていたメソッドを変換できなかったことを理解しています。これに対する回避策はありますか?データベースにアクセスした後でフィルタリングすることはできますが、そのようなボトルネックは避けたいと思います。この計算を行うためにSQL関数を追加することも考えましたが、最初にLINQの可能性を使い果たしたいと思います。

ここにある素敵な投稿では、クエリの前に年齢計算を行う方がよい方法について詳しく説明しています 。LINQで年齢フィルターを確認する最短の方法は?ただし、私の状況では、DateTime.Nowから年齢を計算しているのではなく、データベース内の日付から年齢を計算しています。

4

2 に答える 2

8

LINQ to Entitiesを使用しているため、推奨される解決策はSystem.Data.Objects.EntityFunctionsEFバージョン6の更新:代わりに使用DbFunctions)で定義されたメソッドを利用することであり、クエリサーフェスはそれらをSQLに正常に変換します。この場合、あなたは例えばこれを取りたいです:

o.FormDate.AddYears(-agesFrom)
          .CompareTo(o.FormDate.Subtract(o.Person.DateOfBirth))

そしてそれを次のようなものに変換します

EntityFunctions.DiffMinutes(
    EntityFunctions.AddYears(o.FormDate, -agesFrom),
    EntityFunctions.AddSeconds(
        o.FormDate, 
        EntityFunctions.DiffSeconds(o.FormDate, o.Person.DateOfBirth)
    )
)

目が痛いので、上記が実際に正しいかどうかはわかりませんが。

于 2012-05-15T13:33:06.020 に答える
0

LINQtoEntitiesではこれらのメソッドを使用できません。ただし、クエリがメモリ内で実行される場合は、可能です。.ToList()の前にを使用してみてください.Where

.ToList().Where(0 < o.FormDate.AddYears(-agesFrom)
         .CompareTo(o.FormDate.Subtract(o.Person.DateOfBirth)) && 0 > o.FormDate.AddYears(-agesTo)
         .CompareTo(o.FormDate.Subtract(o.Person.DateOfBirth));

また

.ToList().Where(agesFrom <= CalculateAge(o.Person.DateOfBirth.Value, o.FormDate) 
          && agesTo >= CalculateAge(o.Person.DateOfBirth.Value, o.FormDate);

このようにし.ToList()て、はクエリをメモリに取り込み、メソッドを使用できるようになります。

巨大なデータベースがあるとパフォーマンスが低下しますが、機能します。

于 2012-05-15T13:37:04.150 に答える