如何使用UoW模式在EF Core中检索新ID

问题描述 投票:1回答:3

我在使用UoW模式检索EF Core中新添加的对象的ID时遇到问题。我有这项服务:

public class OrderService : IOrderService
{
    private IUnitOfWork _uow;
    private IOrderRepository _orderRepository;
    private IPaymentRepository _paymentRepository;

    public OrderService(IUnitOfWork uow,
        IOrderRepository orderRepository,
        IPaymentRepository paymentRepository)
    {
        _uow = uow;
        _orderRepository = orderRepository;
        _paymentRepository = paymentRepository;
    }

    public int CreateOrder(Logic.Order order)
    {
        var id = _orderRepository.CreateOrder(order);

        var payment = new Data.Payment();
        payment.OrderId = id;  // at this point, this is -2147353458 something
        _paymentRepository.CreatePayment(payment);

        // committed at this point but I can't get id unless I re-query
        _uow.Commit();

        // this is still -2147353458
        return id;
    }
}

因此,CreateOrder只是添加一个新订单,然后由CreatePayment中的Payment对象返回并使用新生成的ID。这个问题因为添加之后,它还没有提交,所以EF Core生成一个临时ID(类似于-2147483324)所以这就是我得到的。然后我将此传递给付款,但这部分是可以的,因为我认为EF正在跟踪它。问题是我返回UI。

UI调用该服务,提交后,我无法获取该ID。这几个小时以来一直是我的问题。

entity-framework design-patterns entity-framework-core unit-of-work
3个回答
0
投票

我最近也遇到了同样的问题。我在这里只是为了分享我的解决方案供参考。

您可以尝试使用EF关系,而不是为Id提交事务。

例如:付款和订单模型

public class Order
{
  public int Id{ get; set; }

  public Payment Payment { get; set; }
}

public class Payment
{
  public int Id{ get; set; }

  public int OrderId{ get; set; }

  [ForeignKey("OrderId")]
  public Order Order { get; set; }
}

然后在您的交易中,您只需将订单分配给付款,EF将在提交交易时自动将创建的订单ID插入付款:

public int CreateOrder(Logic.Order order)
{
     _orderRepository.CreateOrder(order);

    var payment = new Data.Payment();
    payment.Order = order;
    _paymentRepository.CreatePayment(payment);

    _uow.Commit();

    return order.id;
}

0
投票

你需要创建一个抽象方法,就像你的Uow中的“void Commit(EntityBase entity)”一样,在方法内部调用saveChanges这样你确保内存地址是相同的,所以在方法之外你可以访问属性ID,如果你使用的是Mapper,请小心,因为这可能会改变你的内存地址。在调用UoW.Commit之后,请确保您正在使用映射器!

 public class EntityBase
{
  public int Id {get;set}
}

public class AnyOtherEntity : EntityBase
{
}

public void Commit(EntityBase entity)
{
  yourContext.SaveChanges(entity);
}

Uow.Commit(AnyOtherEntity);

AnyOtherEntity.Id;

-1
投票

如果要立即检索生成的唯一ID,则除了提交事务之外没有其他选项。也,

    // this is still -2147353458
    return id;

提交后你不能指望改变原始类型。您应该通过order.Id获取它,因为在提交的事务之后,EF将更新实体,因为EF正在跟踪实体。

public int CreateOrder(Logic.Order order)
{
    _orderRepository.CreateOrder(order);
    // commit the transaction
    _uow.Commit();
    var payment = new Data.Payment();
    // Get the id of inserted row
    payment.OrderId = order.Id;  
    _paymentRepository.CreatePayment(payment);
    _uow.Commit();
    return order.Id;
}
© www.soinside.com 2019 - 2024. All rights reserved.