c# - Entity Framework 6 : Insert or Update

标签 c# entity-framework

我想使用 Entity Framework 在表中插入或更新一行,具体取决于表中是否已存在主键(字符串)。

我正在使用以下代码来执行我从此处获得的代码:Insert or update pattern

private void InsertOrUpdate(ServiceMonitoring sm)
{
    try
    {
        using (var context = new MyDBEntities())
        {
            context.Entry(sm).State = sm.serviceName == null ?
                EntityState.Added :
                EntityState.Modified;
            context.SaveChanges();
        }
        log.Info("ServiceMonitoring updated");
    }
    catch (Exception ex)
    {
        log.Error("Error updating ServiceMonitoring");
        log.Debug(ex.Message);
    }

}

当行(例如 serviceName = "MyService")已经存在时它工作正常。然后执行更新。但是,如果该行不存在,则 INSERT 失败并且我收到以下错误消息:

Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded.

非常感谢任何帮助!

最佳答案

更新或插入模式与 MSDN 示例中的主键一起工作的原因是因为它被标记为 Identity 字段。当您将实体添加到 DbContext 时,EF 会为 Id 字段提供默认值 0,并且数据库会在执行 INSERT 时为该行分配一个唯一值。

您已尝试错误地调整“更新或插入”模式以使用属性 serviceName,解决方案是使用您引用的 MSDN 文章提供的模式,或执行一个查询。

为了完整起见,为什么您的改编不起作用? 因为您传入了一个 ServiceMonitoring 对象并期望 context.Entry(sm) 查询您的数据库以获取正确的数据行。它没有,先生。因此,在您的情况下,EntityState.Added 基本上是无法访问的代码。

private void InsertOrUpdate(ServiceMonitoring sm)  
{
    try
    {
        //this brand new DbContext instance has not queried your database, and is not tracking any objects!
        using (var context = new MyDBEntities())  
        {
            //if (sm.serviceName is null) <- should never be null, as it's the ServiceMonitoring object you are passing into the function.
            //The DbContext.Entry() does not know whether or not this actually exists in the database, it only allows you to inform
            //EF about the state of the object.
            context.Entry(sm).State = sm.serviceName == null ?  //<- Always false (unless you *really* want a serviceName to not have a name)
                EntityState.Added : // <- code unreachable
                EntityState.Modified; //This is where the exception occurs, your code is always generating an UPDATE statement.
                                        //When the entry exists in the database, EF's generated UPDATE statement succeeds.
                                        //When the entry does not exist, the UPDATE statement fails.
            context.SaveChanges();
        }
        log.Info("ServiceMonitoring updated");
    }
    catch (Exception ex)
    {
        log.Error("Error updating ServiceMonitoring");
        log.Debug(ex.Message);
    }
}

关于c# - Entity Framework 6 : Insert or Update,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49798978/

相关文章:

c# - AutoMapper 将源对象上的单个列表映射到目标对象上的两个列表

c# - X文档 : saving XML to file without BOM

c# - 有没有办法概括 Action 和 Action<T>?

c# - 清理 roslyn 成员声明语法标识符

c# - 如何在 Entity Framework 7 中重新加载模型?

c# - EF 代码优先 : Many-to-Many + Additional Property

c# - 互斥体不再工作

entity-framework - 如何调用 lambda 表达式中的方法在 Entity Framework 中运行?

c# - DbContext/Ninject Dependency GetService Slow SingleOrDefault 在负载测试下

c# - 首先使用 EF 代码将 datetime2 数据类型转换为 datetime 数据类型错误?