エンティティへのLINQ:“ select”でContainsを使用一部が予期しないエラーをスローします
-
03-07-2019 - |
質問
Entity Frameworkオブジェクトに対するLINQクエリがあります。クエリの概要は次のとおりです。
//a list of my allies
List<int> allianceMembers = new List<int>() { 1,5,10 };
//query for fleets in my area, including any allies (and mark them as such)
var fleets = from af in FleetSource
select new Fleet
{
fleetID = af.fleetID,
fleetName = af.fleetName,
isAllied = (allianceMembers.Contains(af.userID) ? true : false)
};
基本的に、私がやっているのはフリートのセットを取得することです。 allianceMembersリストには、私と同盟しているすべてのユーザーのINTが含まれています。フリートの所有者がそのリストに含まれている場合はisAllied = trueに設定し、そうでない場合はfalseに設定します。
これを行うと、例外が表示されます:&quot; LINQ to Entitiesはメソッド 'Boolean Contains(Int32)' method&quot;
を認識しませんクエリのwhere部分にcontainsを使用した場合、このエラーが発生することは理解できますが、なぜselectで取得するのですか?この時点までに、クエリが実行され、結果が返されたと想定します。この小さなコードは、データを制約するものではありません。
isAlliedフラグを設定して必要なことを他にどのように達成できるかについてのヒントはありますか?
ありがとう
解決
var fleets = from af in FleetSource;
var x = from u in fleets.ToList()
select new Fleet
{
fleetID = u.fleetID,
fleetName = u.fleetName,
isAllied = (allianceMembers.Contains(u.userID) ? true : false)
}
フリートで ToList()
を呼び出してクエリを実行すると、後で Contains()
を使用できます。
他のヒント
これは以前の回答から密かになりました...
サポートされていません。
INとJOINは同じ演算子ではありません(INによるフィルタリングはクエリのカーディナリティを変更しません)。
そのようにする代わりに、結合メソッドを使用します。クエリ演算子を使用せずに理解することはやや困難ですが、一度取得すれば、それが得られます。
var foo =
model.entitySet.Join( //Start the join
values, //Join to the list of strings
e => e.Name, // on entity.Name
value => value, //equal to the string
(ModelItem ent, String str) => ent);//select the entity
ここではクエリ演算子を使用しています
var foo = from e in model.entitySet
join val in values on
e.Name equals val
select e;
基本的に、エンティティフレームワークはLINQクエリをSQLステートメントに変換しようとしますが、 Contains
を処理する方法を知りません。
代わりにできることは、データベースから艦隊を取得し、後でisAlliedプロパティを設定することです。
var fleets = (from af in FleetSource
select new Fleet
{
fleetID = af.fleetID,
fleetName = af.fleetName,
userId = af.userId
}).AsEnumerable();
foreach (var fleet in fleets)
{
fleet.isAllied = (allianceMembers.Contains(fleet.userID) ? true : false);
}
私の上の誰もが間違っている!!! (違反なし...)&quot; Contains&quot;のIListオーバーロードを使用しているため、機能しません。 &quot; Contains&quot;のIEnumerableオーバーロードではありません。次のように変更します。
allianceMembers.Contains<int>(af.userID)
&lt; int&gt;
を追加することにより、IListオーバーロードの代わりにIEnumerableオーバーロードを使用するようコンパイラーに指示しています。