实体框架不保存更改

Posted

技术标签:

【中文标题】实体框架不保存更改【英文标题】:Entity Framework not saving changes 【发布时间】:2012-03-04 21:45:21 【问题描述】:

我有一个 MVC Web 应用程序,它使用 SQL Server 2008 作为后端数据库以及实体框架。该应用程序运行良好,并且从数据库中提取数据也很好。我的问题是,当它更新数据时,它似乎没有保存它。我正在使用以下功能:

    public void SaveProduct(Product product)
    
        if (product.ProductID == 0)
        
            context.Products.Add(product);
        

        context.SaveChanges(); // Breakpoint here
    

此函数在我的存储库代码中定义。我在上面注释的行上设置了一个断点,并且应用程序在该行中断,所以我知道它击中了该行并且上下文对象中的更改都很好。没有错误发生,EF 出于某种原因根本没有保存更改。

我相信我的连接字符串是正确的,因为它可以很好地提取数据,但这里以防万一:

<connectionStrings>
    <add name="EFDbContext" connectionString="Data Source=localhost;Initial Catalog=WarehouseStore;Integrated Security=True;Pooling=False" providerName="System.Data.SqlClient"/>
</connectionStrings>

有人对可能导致这种情况的原因有任何想法吗?

【问题讨论】:

假设您正在针对 SQL Server 运行 :-) 您是否打开了 SQL 分析器并查看 EF 是否正在向数据库发送任何查询?在任何保存更改完成之前,应该有一个来自 EF 的分析器中的登录条目。 您是否检查过是否点击了context.Products.Add(product); 如果没有,则没有保存任何内容。 @veblock - 我还没有添加产品的视图,所以我还不能测试那个部分 【参考方案1】:

如果您使用插入/更新功能,则必须涵盖这两种情况:

if (product.ProductID == 0)

    context.Entry(product).State = EntityState.Added;

else

    context.Entry(product).State = EntityState.Modified;

context.SaveChanges();

【讨论】:

EF 是否有理由不知道这一点而没有被告知...毕竟我调用了 add 方法。它适用于编辑现有 编辑现有的时,首先从 EF 获取它,因此 EF 会跟踪对象的状态。添加新对象时,您会在 EF 之外创建对象,因此当您添加它时,您必须明确告诉 EF 添加它。 我到处寻找,但没有找到我要找的东西,我在尝试更改密码时正在做同样的事情。但在我重新启动我的解决方案之前,我的更改无法访问。是 EF6 和 MVC5 asp.net 请帮忙。【参考方案2】:

感谢@veblok,我找到了问题的解决方案。 DbContext 类中有一个选项可以防止 EF 默认跟踪对象。 删除后,EF 开始按预期运行。

 public class My Context : DbContext 
  public MyContext()
  
        // REMOVE this or use veblok's solution
        this.Configuration.AutoDetectChangesEnabled = false;            
  
  ...
 

【讨论】:

AutoDetectChangesEnabled 属性可以极大地提高只读查询的性能(和内存占用) - 因此,如果您在代码库中发现它,请不要在不检查的情况下将其删除。如果您只是在执行复杂读取的方法中进行简单更新,那么您可能需要为更新创建一个新的数据上下文【参考方案3】:

你可以使用上下文的Create方法:当你有一个相关实体时,一般使用这个方法

public void SaveProduct(Product product)
    
        if (product.ProductID == 0)
        
            product = context.Products.Create();
            product.property = ...;
            product.property = ...;

            context.Products.Add(product);
    

    context.SaveChanges(); // Breakpoint here

【讨论】:

【参考方案4】:

我遇到了同样的问题。 context.Entry(product).State = EntityState.Modified; 给了我一个错误。有趣的解决方案是使用DbSetMigrationsExtensions.AddOrUpdate() 方法。 此方法是 DbSetMigrationExtensions 的一部分,您需要指定以下命名空间才能使用此扩展方法:

using System.Data.Entity.Migrations;

public void SaveProduct(Product product)
    
        context.Set<Product>().AddOrUpdate(product);

        context.SaveChanges();
    

【讨论】:

它并非完全为此目的而设计,但它可能适用于您的目的......请参阅***.com/questions/31272455/…【参考方案5】:

我的问题略有不同。我的模型说数据库正在分配密钥,但我实际上是在我的控制器中创建它并传递它。我注释掉了下面的行,一切都开始工作了:

祝其他可能遇到这种情况的人好运。真是个麻烦!

【讨论】:

【参考方案6】:

确保您的表有一个主键。

如果是这样,您会在 dbcontext 中找到这一行

entity.HasNoKey();

【讨论】:

以上是关于实体框架不保存更改的主要内容,如果未能解决你的问题,请参考以下文章

实体框架未将更改保存到数据库中

C#实体框架:添加/插入记录并选择他而不保存更改[重复]

实体框架,查询包含上下文更改的dbset,而不调用保存更改

无法使用实体框架保存数据库更改

实体框架保存多对多的更改

实体框架 ChangeTracker 流并保存到查询