Entity framework ASP.NET OData-使用Delta实现修补程序<;T>;使用数据传输对象

Entity framework ASP.NET OData-使用Delta实现修补程序<;T>;使用数据传输对象,entity-framework,asp.net-web-api,odata,Entity Framework,Asp.net Web Api,Odata,在我的OData控制器中,我将EF实体转换为DTO,因为该实体包含许多UI不使用的字段 这个问答()展示了如何将ODataURI中的查询选项应用于EF查询并返回DTO。这太棒了,这意味着我得到了查询数据库的好处,也得到了序列化较小实体的好处 但是,当我需要更新实体时,如何将带有补丁字段的增量应用于实体 实体中的字段名与DTO不匹配 我可以使用Delta中的changedfields集合,但是我需要映射所有字段名,并使用反射来更新实体中的所有属性 有更好的办法吗 我应该使用我的实体而不是DTO,并

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

这个问答()展示了如何将ODataURI中的查询选项应用于EF查询并返回DTO。这太棒了,这意味着我得到了查询数据库的好处,也得到了序列化较小实体的好处

但是,当我需要更新实体时,如何将带有补丁字段的增量应用于实体

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

我可以使用Delta中的changedfields集合,但是我需要映射所有字段名,并使用反射来更新实体中的所有属性

有更好的办法吗

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


我是否应该回到WebAPI并使用单独的更新函数,这些函数只接受所需的参数,例如UpdateStartDate(int id,DateTime newStartDate)

我刚刚遇到了同样的问题,并发现以下链接很有帮助:

为了繁荣起见,以下代码使用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);
}

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

是否使用automapper定义映射?是的,我使用automapper进行映射。这不会更新模型中的所有属性,而不仅仅是更改的属性吗?生成的SQL是否只包含修补程序请求中传递的属性?我的理解是,将
dto
映射到
实体
将最终设置
dto
对象的所有属性,这不是我们想要的补丁。
Mapper.CreateMap<DbEntity, DtoEntity>()
            .ForMember(dest => dest.Example, opt => opt.ExplicitExpansion());