在我的OData控制器中,我将我的EF实体转换为DTO,因为该实体包含很多字段,而这些字段并未被UI使用。
此问答(ASP.NET WebApi OData support for DTOs)显示了如何将OData URI中的查询选项应用于EF查询并返回DTO。这很好,这意味着我可以获得查询数据库的好处以及序列化较小实体的好处。
但是,当我需要更新时,如何将带有修补字段的Delta应用于我的实体?
实体中的字段名称与DTO不匹配。
我可以使用Delta中已更改的字段集合,但之后我会映射所有字段名称并使用反射来更新实体中的所有属性。
有更好的方法吗?
我应该使用我的实体而不是DTO,并使用odata $ select参数来减少线上数据的大小。
我是否应该恢复到WebAPI并拥有仅采用所需参数的单独更新函数,例如UpdateStartDate(int id,DateTime newStartDate)
答案 0 :(得分:4)
我刚遇到同样的问题,发现以下链接有用:http://qimata.com/?p=1381
为了繁荣,下面是使用AutoMapper将数据库实体映射到DTO的代码,然后将修补程序应用于DTO对象,然后使用AutoMapper在保存之前映射回数据库实体: / p>
[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());
我还必须在我的DbContext构造函数中使用Configuration.LazyLoadingEnabled = false;
禁用延迟加载。