Entity framework 如何使用UoW模式在EF Core中检索新ID
使用UoW模式检索EF Core中新添加对象的ID时遇到问题。我有以下服务:Entity framework 如何使用UoW模式在EF Core中检索新ID,entity-framework,design-patterns,entity-framework-core,unit-of-work,Entity Framework,Design Patterns,Entity Framework Core,Unit Of Work,使用UoW模式检索EF Core中新添加对象的ID时遇到问题。我有以下服务: public class OrderService : IOrderService { private IUnitOfWork _uow; private IOrderRepository _orderRepository; private IPaymentRepository _paymentRepository; public OrderService(IUnitOfWork uo
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只是添加一个新订单,然后返回新生成的ID,并由CreatePayment中的Payment对象使用。这个问题是因为在添加之后,它还没有提交,所以EF Core生成了一个临时id(类似于-2147483324),这就是我得到的。然后我把它传递给付款,但这部分是可以的,因为我认为EF正在跟踪它。问题是我返回到UI的内容
该服务由UI调用,提交后,我无法获取ID。这是我几个小时以来的问题。如果要立即检索生成的唯一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;
}
我最近也遇到了同样的问题。我在这里只是分享我的解决方案供参考 您可以尝试利用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;
}
您需要创建一个抽象方法,就像Uow中的“void Commit(EntityBase entity)”一样,在方法内部调用saveChanges这样您可以确保内存地址相同,因此在方法外部您可以访问属性Id,如果使用某些映射器,请小心,因为这可能会更改内存地址。确保只有在调用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;
不幸的是,传递的顺序不是上下文直接操作的顺序,因此它没有获得ID值。在传递到CreateOrder时,它映射到EF跟踪的正确Order对象。您不需要提交写入来检索ID。只需在调用SaveChanges()之前进行事务处理,然后让您的工作单元提交或回滚。请重新格式化此答案,以便更容易理解。