我在使用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。这几个小时以来一直是我的问题。
答案 0 :(得分:0)
我最近也遇到了同样的问题。在这里只是为了分享我的解决方案以供参考。
您可以尝试利用EF关系,而不是为ID提交交易。
Ex:付款和订单模型
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;
}
答案 1 :(得分: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;
答案 2 :(得分:-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;
}