IQueryable、Where、Guidおよび
-
03-07-2019 - |
質問
MVC Storefrontコードを使用して作業を進めており、dbml / dataコンテキストの外側で、pocoであるリポジトリ、サービス、およびモデルのパスをたどろうとしています。テストを書き始めて、理解できない方法で物事が失敗するまで、実際にフォローするのはかなり簡単です。
私の場合、主キーはintフィールドではなくuniqueidentifierです。リポジトリはIQueryableを返します:
public IQueryable<Restaurant> All()
{
return from r in _context.Restaurants select new Restaurant(r.Id)
{
Name = r.Name
};
}
この場合、Restaurantはもちろん_context.Restaurants.RestaurantではなくModels.Restaurantです。
All()に対するサービスクラス(またはリポジトリユニットテスト)でのフィルタリング、これは期待どおりに機能します:
var results = Repository.All().Where(r => r.Name == "BW<3").ToList();
これはうまく機能し、Model.Restaurantが1つあります。さて、pkidで同じことを試してみると:
var results = Repository.All().Where(r => r.Id == new Guid("088ec7f4-63e8-4e3a-902f-fc6240df0a4b")).ToList();
次で失敗する場合:
The member 'BurningPlate.Models.Restaurant.Id' has no supported translation to SQL.
r =&gt;であると人々が言う類似の投稿を見た場合。 r.Idは[Model.Restaurants]はlinq2sqlレイヤーが認識しないクラスレベルです。私にとって、それは最初のバージョンも動作しないことを意味しています。もちろん、私のpkがintであれば、それは問題なく動作します。
ここで実際に何が起こっているのですか?主が知っているように、一つの仕事ともう一つの仕事をすることはあまり直感的ではありません。私は何を誤解していますか?
解決
ここでの問題は、コンストラクターのオーバーロードを使用し、クエリがそれを埋めることを期待しているためだと思います。実際の投影自体。そうしないと、LinqはそれをSQLクエリに含めません。
したがって、次のようにビットを書き換えます:
return from r in _context.Restaurants select new Restaurant()
{
Id=r.Id,
Name = r.Name
};
これで修正されるはずです。
他のヒント
このコードを実際に入力していません。試しましたか
var results = Repository.All()。Where(r =&gt; r.Id.Equals(new Guid(&quot; 088ec7f4-63e8-4e3a-902f-fc6240df0a4b&quot;))。ToList()
忍者
これはおそらく、クエリでGUIDをインスタンス化しようとしているという事実と関係があり、LINQ to SQLはオブジェクトが作成される前にそれを実際のSQLコードに変換しようとしていると思います。
クエリではなく、クエリの前にインスタンス化を試してください。