15

これにより、今日は問題が尽きることがありません。この簡単なクエリがあります

var result =
    DataContext.Accommodations.Where(a => 
        (criteria.MinPrice == null || a.AccommodationRates.Any(r => r.From >= criteria.MinPrice)) &&
        (criteria.MaxPrice == null || a.AccommodationRates.Any(r => r.To <= criteria.MaxPrice)) &&
        (criteria.Locations == null || criteria.Locations.Count == 0 || a.AccommodationPlaceJoins.Any(j => criteria.Locations.Contains(j.Place.PlaceName)))
);

このクエリの最後の行が問題を引き起こしています

(criteria.Locations == null ||
 criteria.Locations.Count == 0 ||
 a.AccommodationPlaceJoins.Any(j => criteria.Locations.Contains(j.Place.PlaceName)))

それが与えるエラーは

タイプ 'System.Collections.Generic.IList`1' の定数値を作成できません。このコンテキストでは、プリミティブ型 (Int32、String、および Guid など) のみがサポートされます。

私はリストを作成しようとさえしていません。私がここでやろうとしているのは、場所に関連付けられている宿泊施設を取り戻すことです (宿泊施設テーブルを介して宿泊施設テーブルにリンクされている場所テーブルの場所名が、条件の場所名のいずれかと等しい場合)。 .Locations (IList 型)。

この行をこれに変更しようとしましたが、うまくいきませんでした。

(criteria.Locations == null ||
 criteria.Locations.Count == 0 ||
 a.AccommodationPlaceJoins.Any(j => criteria.Locations.Any(l => l == j.Place.PlaceName)))
4

1 に答える 1

46

EF が作成できない定数値はnull、比較用criteria.Locations == nullです。クエリを 2 つのケースに分割し、クエリの外側で空のリストをチェックする必要があります。たとえば、次のようになります。

var result = DataContext.Accommodations.Where(a => 
    (criteria.MinPrice == null || 
        a.AccommodationRates.Any(r => r.From >= criteria.MinPrice)) &&
    (criteria.MaxPrice == null ||
        a.AccommodationRates.Any(r => r.To <= criteria.MaxPrice)));

if (criteria.Locations != null && criteria.Locations.Count > 0)
{
    result = result.Where(a => a.AccommodationPlaceJoins
        .Any(j => criteria.Locations.Contains(j.Place.PlaceName)));
}

編集

ところで:クエリ全体を作成すると、私の意見では読みやすくなり、データベースに送信する必要があるSQLが簡素化されます。

IQueryable<Accommodation> result = DataContext.Accommodations;

if (criteria.MinPrice != null)
    result = result.Where(a => a.AccommodationRates
        .Any(r => r.From >= criteria.MinPrice));

if (criteria.MaxPrice != null)
    result = result.Where(a => a.AccommodationRates
        .Any(r => r.To <= criteria.MaxPrice));

if (criteria.Locations != null && criteria.Locations.Count > 0)
    result = result.Where(a => a.AccommodationPlaceJoins
        .Any(j => criteria.Locations.Contains(j.Place.PlaceName)));
于 2012-09-05T15:19:17.637 に答える