7

私の OData コントローラーでは、UI で使用されない多くのフィールドがエンティティに含まれているため、EF エンティティを DTO に変換しています。

この質問と回答 ( ASP.NET WebApi OData support for DTOs ) は、OData URI からのクエリ オプションを EF クエリに適用して DTO を返す方法を示しています。これは素晴らしいことです。つまり、DB にクエリを実行する利点と、小さなエンティティをシリアル化する利点を得ることができます。

ただし、エンティティを更新する必要がある場合、パッチを適用したフィールドを含むデルタをエンティティに適用するにはどうすればよいですか?

エンティティのフィールド名が DTO と一致しません。

デルタから変更されたフィールド コレクションを使用できますが、すべてのフィールド名をマップし、リフレクションを使用してエンティティ内のすべてのプロパティを更新する必要があります。

より良い方法はありますか?

DTO の代わりにエンティティを使用し、odata $select パラメーターを使用して、ネットワーク上のデータのサイズを縮小する必要がありますか?

WebAPI に戻って、必要なパラメーターのみを受け取る個々の更新関数を使用する必要があります。たとえば、UpdateStartDate(int id, DateTime newStartDate)

4

1 に答える 1

5

同じ問題に遭遇したばかりで、次のリンクが役立つことがわかりました: http://qimata.com/?p=1381

繁栄のために、AutoMapper を使用してデータベース エンティティを DTO にマップするコードを次に示します。次に、DTO オブジェクトにパッチを適用し、保存する前に AutoMapper を使用してデータベース エンティティにマップし直します。

[AcceptVerbs("PATCH", "MERGE")]
public virtual async Task<IHttpActionResult> Patch([FromODataUri] int key, Delta<DtoEntity> delta, CancellationToken cancellationToken)
{
    Validate(delta.GetEntity());

    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    var entity = await _genericRepository.FindAsync(cancellationToken, key);
    var dto = Mapper.Map<DtoEntity>(entity);
    delta.Patch(dto);
    Mapper.Map(dto, entity);
    await _context.SaveChangesAsync(cancellationToken);
    return Updated(dto);
}

言及する価値のあるもう 1 つのことは、EntityFramework で AutoMapper を使用する場合は、ナビゲーション プロパティの自動拡張に注意することです。ExplicitExpansion次のメソッドを使用して、拡張を無効にすることができます。

Mapper.CreateMap<DbEntity, DtoEntity>()
            .ForMember(dest => dest.Example, opt => opt.ExplicitExpansion());

Configuration.LazyLoadingEnabled = false;また、DbContext コンストラクターで遅延読み込みを無効にする必要がありました。

于 2015-06-03T14:01:15.880 に答える