如何在 C# 中有效地编辑内存对象

how to edit in memory object efficiently in C#

我正在使用 Entity framework 带有工作单元的核心存储库模式 (C#) 我想知道更新对象的有效方法

型号Class

public class Item : IEntity
{
    public string Label { get; set; }
    public double Quantity { get; set; }
    public string Description { get; set; }
    public int DisplayPriority { get; set; }
    public ItemStatus Status { get; set; }
    public string ShopperComment { get; set; }
}

DTO类

public class ItemDto
{
    public string Label { get; set; }
    public double Quantity { get; set; }
    public string Description { get; set; }
    public int DisplayPriority { get; set; }
    public string ShopperComment { get; set; }

}

控制器代码

[HttpPut("{itemId}")]
public async Task<IActionResult> Update(Guid itemId,[FromBody]ItemDto itemDto)
{
    try
    {
        if (!_permissionsManager.UserHasAnAllowedRole(User, new List<string>() { "SuperAdmin", "Administrator", "Item.Update" }))
        {
            return Unauthorized(new ErrorDto("Method not allowed"));
        }

        var item = await _unitOfWork.Items.Get(itemId);

        if (item == null)
        {
            return BadRequest(new ErrorDto("Item does not exist"));
        }


        item.Label = itemDto.Label;
        item.Status = itemDto.Status;
        item.ShopperComment = itemDto.ShopperComment;
        item.Description = itemDto.Description;
        item.Quantity = itemDto.Quantity;
        item.DisplayPriority = itemDto.DisplayPriority;

        await _unitOfWork.SaveChangesAsync();

        return Ok(item.toItemDto());
    }
    catch (Exception x)
    {
        _log.Error("[Update] Failed", x);
        return StatusCode(500, new ErrorDto(x.Message));
    }
}

我不希望从 ItemDto 到 Item 的映射来更新控制器中的 Item 对象,我怎样才能通过松散耦合以灵活的方式做到这一点,因为我不想在控制器中添加对象依赖关系

首先,您可以为您的模型声明一个接口,也就是 IItem 并在合同中执行(如果您不想在控制器中引用具体类型并担心耦合):

public interface IItem {
    string Label { get; set; }
    double Quantity { get; set; }
    string Description { get; set; }
    int DisplayPriority { get; set; }
    ItemStatus Status { get; set; }
    string ShopperComment { get; set; }
}

为您的特定模型使用继承 - ItemDto : IItem,Item : IItem,IEntity.

之后你可以为此创建一个特定的服务,如 IItemMapper 服务并声明名为 UpdateItem(IItem dbItem, IItem updated) 的方法,并使用 Entity Framework 的另一个 built-in 方法为了避免对每个 属性 进行枚举 - 例如:

public void UpdateItem(IItem dbItem, IItem updated) {
    ...
    //injections/ logic/ validation
    await _unitOfWork.Entry(dbItem).CurrentValues.SetValues(updated);
}

另外,作为一个选项,你甚至可以使用Automapper来避免枚举每个属性.

您根本没有遵循存储库模式。存储库模式的目的是在数据层(即 database/tables)和业务域(您的 类)之间创建抽象。

这样做的目的是降低复杂性以及在发生变化时同时更新数据层和业务层的要求。

您的代码两者都没有。

那你就错过了 DTO 的重点。这些的目的是重新设计业务实体,以便它们在 API 中更好地工作(因为 DTO 代表“数据传输对象”)。如果你不这样做,那么使用它们就没有意义。直接公开您的 EF 实体。

现在,回答您的实际问题。最简单的方法是使用像 automapper 这样的库,它会为您处理复制。