7

在我的 OData 控制器中,我将我的 EF 实体转换为 DTO,因为该实体包含许多 UI 不使用的字段。

这个问答(ASP.NET WebApi OData support for DTO)展示了如何将 OData URI 中的查询选项应用到 EF 查询并返回 DTO。这很好,这意味着我得到了查询数据库的好处,也得到了序列化较小实体的好处。

但是,当我需要更新它时,如何将带有修补字段的 Delta 应用到我的实体?

实体中的字段名称与 DTO 不匹配。

我可以使用来自 Delta 的已更改字段集合,但随后我将映射所有字段名称并使用反射来更新实体中的所有属性。

有没有更好的办法?

我是否应该使用我的实体而不是 DTO 并使用 odata $select 参数来减少线路上数据的大小。

我是否应该恢复到 WebAPI 并拥有仅采用所需参数的单独更新函数,例如 UpdateStartDate(int id, DateTime newStartDate)

4

1 回答 1

5

我刚刚遇到了同样的问题,发现以下链接很有帮助:http: //qimata.com/ ?p=1381

为了繁荣,这里是使用 AutoMapper 将数据库实体映射到 DTO 的代码,然后将 Patching 应用于 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);
}

值得一提的另一件事是,在将 AutoMapper 与 EntityFramework 一起使用时,请注意导航属性的自动扩展。您可以使用以下ExplicitExpansion方法禁用扩展:

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

Configuration.LazyLoadingEnabled = false;我还必须在我的 DbContext 构造函数中禁用延迟加载。

于 2015-06-03T14:01:15.880 回答