2

シリアライザーに渡すために、一部の POCO エンティティを EF からカットダウン ビュー モデル表現に投影する必要があります。この状況のエンティティは、Shipment と Requisition であり、0..1 の関係があります。ビュー モデルを渡さないと、要求と出荷の間の循環参照をシリアル化しようとして、スタック オーバーフロー例外がスローされます。

return db.ShipmentRequisitions
                .Include(c => c.Shipment)
                .Select(r => new ViewModels.Requisition
                {
                    ID = r.ID,
                    ...
                    Shipment = r.Shipment != null ? new ViewModels.Shipment
                    {
                        ID = r.Shipment.ID,
                        ...
                    } : null
                }).AsQueryable();

Shipment が null の場合、r.Shipment.ID にアクセスしようとすると例外が発生します。上記のように null チェックを追加したところ、次の例外が発生しました。

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

null チェックを追加する前に、ネストされた ViewModels.Shipment を select の一部として作成できてよかったので、これは奇妙に思えます。

コール スタックに EF が見られるので、純粋な LINQ で試してみるために、単純なオブジェクトだけを使用した簡単なテスト プロジェクトで試してみました。

var user = users.Select(u => new ViewModel.User
                {
                    Id = u.Id,
                    Profile = u.Profile != null ? new ViewModel.Profile
                    {
                        Id = u.Profile.Id
                    } : null
                }).ToList();

驚いたことに、うまくいきました。最初のコード サンプルでは、​​何が機能しないのかよくわかりません。

アップデート

選択の一部として次のようなことを行う場合、私はそれを発見しました:

.Select(r => new ViewModels.Requisition
                    {
                        ID = r.ID,
                        ShipmentDescription = r.Shipment.Description
                    })

これにより、必要な Shipment プロパティが単一の DTO に効果的にフラット化されます。ここで、Description プロパティを設定するときに、いずれかのレコードで Shipment が null の場合、NullReferenceExcetion を取得することを期待します。しかし、それは起こりません。LINQ は例外を抑制しているようで、ShipmentDescription は null と同じように渡されます。ネストされたプロパティごとに、Shipment のインライン is null チェックを行う手間が省けます。残念ながら、フラット化していないネストされたオブジェクトを作成する場合、これは同じ種類のものには拡張されないようです。

4

2 に答える 2

1

クラス内のすべてのプロパティが nullable である場合、null チェックなしでViewModels.Shipmentオブジェクトを組み込むことができます。ただし、オブジェクトは出荷がない場合にのみ null 値で作成されるため、少し面倒です。ViewModels.RequisitionShipmentShipment

向きを変えることもできます。Shipmentのコレクションを含むモデルを選択Requisitionsします。アプリケーションの残りの部分をあまり台無しにしない場合は、試してみる価値があります。

于 2012-09-19T23:06:53.970 に答える
0

問題はこの行です:

.SingleOrDefault(r => r.ID == id);

EFは式r.ID == idをSQLに変換しようとしており、管理していません。

解決策は、行を次のように変更することです。 .ToEnumerable().SingleOrDefault(r => r.ID == id);

IQueryableのみがSQLに変換され、IEnumerableは変換されないため、これは機能します。

于 2012-09-19T15:19:35.007 に答える