Why does context.SaveChanges() update every row in the table?

how to update record using entity framework in c#
update only modified fields in entity framework 6
entity framework update
dbcontext update
entity framework update multiple records
entity framework add or update
entity framework bulk update
entity framework savechanges example

I wrote some code using C# and Entity Framework 6 (EF6) with MySql. The IDE is Visual Studio 2019 preview.

I installed these packages:

<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>

Inserting and Selecting are works correctly but Updating works wired.

I put some number(something like 2 or 100) into tbx_CarId and I expected that EF6 updates only ONE row, but it updates every low in the table.

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());
        }
    }
}

The method context.SaveChanges() always returns an exact number, 1, and on the console window, "numOfSavedLows: 1" is printed.

But the every row is changed whenever I execute that method.

Also, the logger of EF6 writes on the console something like this:

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

Please look at the line -- Completed in 6 ms with result: 16 The number(in this case, 16) is the count of every row in Car table.

Why does EF6 update every low? How can I fix it?

The rest of the codes are here:

[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();
    }
}

and

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

Most of the codes are from here: https://dev.mysql.com/doc/connectors/en/connector-net-entityframework60.html

update 1: The table Cars looks like this (The schema and table are generated by EF6 automatically)

update 2: The values of the rows are like this: Before and After (args are 8, 'new value')

Context.Savechanges() finds all changes in all dbsets(entities) and commit all of them in the database, it is a draw in Entity framework.

Modifying data via the DbContext, the DbContext. Attach method and then "walking the object graph" to set the state of individual properties within the graph explicitly. DbContext Update. The DbContext class provides Update and UpdateRange methods for working with individual or multiple entities. public void Save(Author author) { context.Update(author); context.SaveChanges(); } As with setting the entity's State, this method results in the entity being tracked by the context as Modified. Once again, the context

I guess your entity doesn't have a primary column defined. That way, Entity Framework cannot select the correlating data in the table to your entity and updates every row where "everything" (every entry matches the primary key definition) meets the condition. You need to add something like

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

to your modeled Cars table on your CarId (you don't show this definition)

This only works if you are using CodeFirst, if you are using DbFirst you should check the generated entity of Carsif it's modeled correctly and if you modeled a primary key in your DB.

context.SaveChanges return 0 when updated without any change , is the number of objects updated in the context: Int32 The number of objects written to the underlying database. The number of state entries written to the underlying database. This can include state entries for entities and/or relationships. Relationship state entries are created for many-to-many relationships and relationships where there is no foreign key property included in the entity class (often referred to as independent associations).

As suggested in official EF6 GitHub,

Removing the MapToStoredProcedure in my DbContext fixes the issue.

I would tell you to try removing the "MapToStoredProcedures()" code and see if you get any different result.

Add, Update and Delete Objects in Entity Framework 4.0, When SaveChanges is called, an UPDATE statement is generated and properties were modified, the context will issue an SQL statement updating all property  Third, specify which rows you want to update in the WHERE clause. The WHERE clause is optional. If you omit the WHERE clause, all rows in the table will be updated. The database engine issues a message specifying the number of affected rows after you execute the statement. SQL UPDATE statement examples

Working With Proxies in Entity Framework, context.SaveChanges(); } catch (OptimisticConcurrencyException ex) { Console. that you know will be changed in every update to the underlying table. we updated the row out-of-band using the ExecuteStoreCommand() method to send a  A row context does not propagate through relationships. If you have a row context in a table, you can iterate the rows of a table on the many side of a relationship using RELATEDTABLE, and you can access the row of a parent table using RELATED.

Entity Framework 4.0 Recipes: A Problem-Solution Approach, SaveChanges(); } catch (DbUpdateConcurrencyException ex) { Console. concurrency strategy because rows are not locked when they are updated; rather it is up to a property that you know will be changed in every update to the underlying table. When we call SaveChanges(), Entity Framework generates an update  If the table is empty except for the header, the header row DOES repeat. If I add any content rows to the table, below the header, the header does NOT repeat. If I add a BLANK row between the header and the first row of information, the header DOES repeat, sometimes. The illustration below shows the table, on the next page(s), WITHOUT the

Entity Framework 6 Recipes, For example, you can synchronize two tables by inserting, updating, or deleting rows in one table based on differences found in the other table. One of problems I have is when the rows get "hidden" the select all steps to unhide does not work. It seems to be this one spreadsheet but why I do not know. I do have a Visio 2010 drawing that is linked to this spreadsheet but not sure if somehow that is causing my issues or not.

Comments
  • Are you sure, that 16 rows were updated? Maybe table contains index, and it was rebuild? Have you used profiler to see generated sql code?
  • That can only happen when CarId isn't unique and there are 16 records having CarId == 2.
  • Did you check the State of the Entities in the ChangeTracker of your DbContext? All of them should equal EntityState.Unchanged, except the entity you changed.
  • When you run a database trace (or use hibernatingrhinos.com/products/efprof) to see the exact commands being sent to the database, what is being submitted?
  • Can you go into database and find Car_Update procedure?
  • Still, he only changed one row. The ChangeTracker of the DbContext should contain all elements, but most of them should have a State equal to EntityState.Unchanged.
  • But the table Cars has a primary key... CarId column is the primary key. check this out. i.stack.imgur.com/x1cle.png