为什么context.SaveChanges()更新表中的每一行?

时间:2019-01-03 10:00:25

标签: c# mysql .net visual-studio entity-framework-6

我使用C#和Entity Framework 6(EF6)编写了一些代码 与MySql。 IDE是Visual Studio 2019预览版。

我安装了这些软件包:

<packages>
  <package id="EntityFramework" version="6.2.0" targetFramework="net461" />
  <package id="MySql.Data" version="6.10.8" targetFramework="net461" />
  <package id="MySql.Data.Entity" version="6.10.8" targetFramework="net461" />
</packages>

插入和选择正确进行 但是更新可以进行有线连接。

我在tbx_CarId中输入了一些数字(例如2或100) 而且我希望EF6仅更新一行, 但会更新表格中的每个低点。

private void btn_update_Click(object sender, EventArgs e)
{
    using (MySqlConnection connection = new MySqlConnection(connectionString))
    {
        connection.Open();

        using (Parking context = new Parking(connection, false))
        {
            context.Database.Log = (string message) => { Console.WriteLine(message); };

            int targetId = Int32.Parse(tbx_CarId.Text);
            var blogs = from b in context.Cars
                        where b.CarId == targetId
                        select b;
            Car item = blogs.Single();
            item.Model = tbx_NewModel.Text;
            int numOfSavedLows = context.SaveChanges();
            Console.WriteLine("numOfSavedLows: " + numOfSavedLows.ToString());
        }
    }
}

方法context.SaveChanges()始终返回精确数字1, 在控制台窗口上,将显示“ numOfSavedLows:1”。

但是每当我执行该方法时,每一行都会更改。

此外,EF6的记录器在控制台上这样写:

Started transaction at 2019-01-03 오후 6:47:59 +09:00
`Car_Update`
-- CarId: '2' (Type = Int32, IsNullable = false)
-- Model: 'new value of the model' (Type = String, IsNullable = false, Size = 5)
-- Year: '2013' (Type = Int32, IsNullable = false)
-- Manufacturer: 'Dodge' (Type = String, IsNullable = false, Size = 5)
-- Executing at 2019-01-03 오후 6:47:59 +09:00
-- Completed in 6 ms with result: 16

Committed transaction at 2019-01-03 오후 6:47:59 +09:00
Disposed transaction at 2019-01-03 오후 6:47:59 +09:00

请查看第-- Completed in 6 ms with result: 16行 数字(在本例中为16)是Car表中每一行的计数。

为什么EF6会每低更新一次? 我该如何解决?

其余代码在这里:

[DbConfigurationType(typeof(MySqlEFConfiguration))]
class Parking : DbContext
{
    public DbSet<Car> Cars { get; set; }

    public Parking()
      : base()
    {
        // constructor is empty
    }

    // Constructor to use on a DbConnection that is already opened
    public Parking(DbConnection existingConnection, bool contextOwnsConnection)
      : base(existingConnection, contextOwnsConnection)
    {
        // constructor is empty
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<Car>().MapToStoredProcedures();
    }
}

class Car
{
    public int CarId { get; set; }
    public string Model { get; set; }
    public int Year { get; set; }
    public string Manufacturer { get; set; }
}

大多数代码都来自这里: https://dev.mysql.com/doc/connectors/en/connector-net-entityframework60.html

更新1: 表Cars看起来像 this (模式和表由EF6自动生成)

更新2: 行的值如下所示: BeforeAfter(参数为8,“新值”)

3 个答案:

答案 0 :(得分:0)

Context.Savechanges()查找所有dbsets(实体)中的所有更改,并将所有更改提交到数据库中,这是在Entity框架中进行的绘制。

答案 1 :(得分:0)

我猜您的实体没有定义主列。 这样,Entity Framework无法选择表中与您的实体相关的数据,并在满足“条件”(所有条目均与主键定义匹配)的情况下更新每一行。 您需要添加

[Key, Column("Car_ID_IN_DB"), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int CarId{ get; set;}

Cars上建模的CarId表中(您未显示此定义)

这仅在使用CodeFirst的情况下有效,如果使用的是DbFirst,则应检查Cars的生成实体是否建模正确,以及是否在数据库中建模了主键。

答案 2 :(得分:0)

official EF6 GitHub中的建议,

  

在我的DbContext中删除MapToStoredProcedure可以解决此问题。

我会告诉您尝试删除“ MapToStoredProcedures()”代码,看看是否得到任何不同的结果。