我想知道实体框架如何与纯函数一起工作。我有一个带有更新状态方法的订单类。它不更改当前实例的属性,而是返回一个带有属性更新的新实例。
public class Order {
...
private Order(Order order, string status){
Id = order.Id;
...
Status = status;
}
Guid Id { get; private set; }
...
string Status { get; private set; }
public Order UpdateStatus(string status){
if (Status == "Complete"){
return this;
}
return new Order(this, status);
}
}
问题出现在使用实体框架时。由于返回的顺序与变更跟踪器所跟踪的实例不同,因此实体框架无法正确保存更改。
var order = this.dbContext.Orders.Single(o => o.Id == id);
var newOrder = order.UpdateStatus();
this.dbContext.SaveChanges();
是否有更好的方法来做到这一点,有一个纯函数,仍然有跟踪的变化?
有一个办法,但不是更好。它涉及到操纵EntityFramework的更改跟踪器,这实际上违背了让EntityFramework完成繁重工作并自动跟踪更改的目的。现在你必须手动操作。
我不建议这样做,因为EntityFramework不是为纯函数操作的不可变实体设计的。
var newOrder = order.UpdateStatus();
// Find the old entry being tracked by the change tracker
var entry = dbContext.ChangeTracker.Entries().Where(e => e.Entity == order).FirstOrDefault();
if (entry == null)
throw new InvalidOperationException("Cannot update Order entity because it is not being tracked by the change tracker.");
// Stop tracking the old instance
entry.State = EntityState.Detached;
// Attach new entity to the context (the state is by default Unchanged);
var newEntry = dbContext.Attach(newOrder);
// Change the state from Unchanged to Modified
newEntry.State = EntityState.Modified;
dbContext.SaveChanges();
可以使用dbContext。更新而不是dbContext。可以直接修改状态,但这会导致EntityFramework递归地检查你的实体引用的所有实体,并改变它们的状态。