C# 实体框架不保存更改

C# 实体框架不保存更改,c#,asp.net-mvc-3,sql-server-2008,entity-framework-4.1,C#,Asp.net Mvc 3,Sql Server 2008,Entity Framework 4.1,我有一个MVCWeb应用程序,它使用SQLServer2008作为后端数据库和实体框架。应用程序工作正常,从数据库中提取数据也很正常。我的问题是,当它更新数据时,它似乎没有保存它。我正在使用以下功能: public void SaveProduct(Product product) { if (product.ProductID == 0) { context.Products.Add(product); }

我有一个MVCWeb应用程序,它使用SQLServer2008作为后端数据库和实体框架。应用程序工作正常,从数据库中提取数据也很正常。我的问题是,当它更新数据时,它似乎没有保存它。我正在使用以下功能:

    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>


有人知道是什么原因导致了这种情况吗?

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

if (product.ProductID == 0)
{
    context.Entry(product).State = EntityState.Added;
}
else
{
    context.Entry(product).State = EntityState.Modified;
}
context.SaveChanges();

您可以使用上下文的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
}

多亏了@veblok,我找到了解决问题的方法。 DbContext类中有一个选项可以防止EF在默认情况下跟踪对象。 一旦移除,EF就开始按预期运行

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

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

using System.Data.Entity.Migrations;

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

        context.SaveChanges();
    }
使用System.Data.Entity.Migrations;
公共产品(产品)
{
context.Set().AddOrUpdate(产品);
SaveChanges();
}

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


祝所有可能遇到这种情况的人好运。真是个该死的家伙

确保您的表具有主键

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


entity.HasNoKey()

假设您运行的是SQL Server:-)是否已打开SQL profiler并查看EF是否向数据库发送任何查询?在任何保存更改完成之前,应该有一个EF在profiler中的登录条目。您是否检查了是否点击了
context.Products.Add(product)如果没有,则不会保存任何内容。@veblock-我还没有添加产品的视图,因此我无法测试该部分。是的,这是EF不知道这一点的原因,而我们没有被告知。。。毕竟我调用了add方法。它适用于编辑现有对象当您编辑现有对象时,首先从EF获取它,因此EF跟踪对象的状态。当你添加一个新的时,你在EF之外创建了一个对象,因此当你添加它时,你必须明确地告诉EF添加它。我到处都找了,没有找到我要找的东西,我在尝试更改密码时做了同样的事情。但在重新启动解决方案之前,无法访问我的更改。这是EF6和MVC5 asp.net,请提供帮助。
AutoDetectChangesEnabled
属性可以极大地提高只读查询的性能(和内存占用)-因此,如果您在代码库中找到此属性,请不要在未检查的情况下将其删除。如果您只是在执行复杂读取的方法中执行简单更新,那么您可能需要为更新创建新的数据上下文。它并不是专门为此目的设计的,但它可能适合您的目的。。。看见