繁体   English   中英

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

[英]how to edit in memory object efficiently in C#

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

模型类

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 Object 我怎样才能通过松散耦合以良好的灵活方式做到这一点,因为我不想在控制器中添加对象依赖项

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

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)的方法,并使用实体框架的另一个内置方法以避免枚举每个属性 - 例如:

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

此外,作为一个选项,您甚至可以使用Automapper来避免枚举每个属性。

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

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

您的代码也没有。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM