Asp.net mvc EntityState.Added和Add()之间有什么区别?

Asp.net mvc EntityState.Added和Add()之间有什么区别?,asp.net-mvc,entity-framework,crud,Asp.net Mvc,Entity Framework,Crud,我最近使用它将实体EF添加到我的数据库中: ctx.Entry(payment).State = payments.ID == 0 ? EntityState.Added : EntityState.Modified; 而不是普通的: ctx.Payments.Add(payments); 第二个很好,因为我可以选择是添加还是删除 第一种方法和第二种方法之间的真正区别是什么?为什么没有一个简单的更新项目?例如: ctx.Payments.Update(payments); 哪个将镜像E

我最近使用它将实体EF添加到我的数据库中:

ctx.Entry(payment).State = payments.ID == 0 ? EntityState.Added : EntityState.Modified;
而不是普通的:

ctx.Payments.Add(payments); 
第二个很好,因为我可以选择是添加还是删除

第一种方法和第二种方法之间的真正区别是什么?为什么没有一个简单的更新项目?例如:

ctx.Payments.Update(payments); 
哪个将镜像EntityState。是否修改了一个

这是我正在使用的代码,将我的MVC操作/控制器中的ViewModel设置为我的EF上下文:


通过设置分离实体的状态来添加该实体与调用Add没有区别

您可以在wrapped by DbEntityEntry中看到,将状态设置为Added只会调用InternalSet.Add。从中可以看出,调用Add也只是调用InternalSet.Add。它们的先决条件略有不同,但在您的情况下,两者的先决条件都满足了

在您的例子中,第一种方法的优点在于,相同的代码位可以添加实体,也可以附加实体并将其标记为已修改。正如您所注意到的,没有一种方法可以替代将状态设置为“已修改”

第二个很好,因为我可以选择是添加还是删除

您还可以将状态设置为“已删除”,因此这两种方法都没有优势

为什么没有一个简单的更新项目


可能是因为从EF的角度来看,它的唯一用例是当你做一些奇怪的事情时。分离、序列化、修改、反序列化和重新附加实体可能是框架中的标准,但从EF的角度来看,这些都是高级的低级操作,出错的风险有所增加。例如,当您的模型包含任何也用于并发检查的可修改属性时,序列化-反序列化丢失属性的原始值这一事实意味着并发检查肯定会失败。

通过设置分离实体的状态来添加该实体与调用Add来添加该实体之间没有区别

您可以在wrapped by DbEntityEntry中看到,将状态设置为Added只会调用InternalSet.Add。从中可以看出,调用Add也只是调用InternalSet.Add。它们的先决条件略有不同,但在您的情况下,两者的先决条件都满足了

在您的例子中,第一种方法的优点在于,相同的代码位可以添加实体,也可以附加实体并将其标记为已修改。正如您所注意到的,没有一种方法可以替代将状态设置为“已修改”

第二个很好,因为我可以选择是添加还是删除

您还可以将状态设置为“已删除”,因此这两种方法都没有优势

为什么没有一个简单的更新项目


可能是因为从EF的角度来看,它的唯一用例是当你做一些奇怪的事情时。分离、序列化、修改、反序列化和重新附加实体可能是框架中的标准,但从EF的角度来看,这些都是高级的低级操作,出错的风险有所增加。例如,当您的模型包含任何也用于并发检查的可修改属性时,序列化-反序列化丢失属性的原始值这一事实意味着并发检查肯定会失败。

对于普通EF,您几乎不需要将状态设置为EntityState。已修改:加载实体并修改其属性足以自动检测到该状态。显式地将状态设置为EntityState.Modified可能是解决代码其余部分所做的事情所必需的,例如从一个上下文中分离实体并将它们附加到另一个上下文。你能详细说明为什么在你的案例中需要它吗?@hvd:是的,我正在从一个MVC应用程序ViewModel传递到我的实体模型。我已经用主场景更新了这个问题。使用纯EF,您几乎不需要将状态设置为EntityState。修改:加载实体并修改其属性就足以自动检测到它。显式地将状态设置为EntityState.Modified可能是解决代码其余部分所做的事情所必需的,例如从一个上下文中分离实体并将它们附加到另一个上下文。你能详细说明为什么在你的案例中需要它吗?@hvd:是的,我正在从一个MVC应用程序ViewModel传递到我的实体模型。我已经用主要场景更新了这个问题。
IList<Payments> newPayments = activityViewModel.Payments.Select(p => mapper.Map<PaymentViewModel, Payments>(p)).ToList();

foreach (var payments in newPayments)
{
    ctx.Entry(payments).State = payments.ID == 0 ? EntityState.Added : EntityState.Modified;
    ctx.Payments.Add(payments);
}

ctx.SaveChanges();