JonathanReed
JonathanReed

Reputation: 3

Better way to update/insert values using EF

I am trying to solve a problem as well as learn and improve my code skills here.

I am using Entity Framework and am tasked with writing to a SQL table, where I can update or insert based on whether a row exists or not. If it doesn't exist then add it, if it does exist then update it if required.

I have 2 lists, the first list is the EF type from the table that I am writing to. The second list is a class which is made up from a SQL query but shares some of the columns from the table which needs updating, thus if they differ then update the table with the differing property values.

foreach (var tbl in Table_List)
{
    foreach (var query in SQL_Query)
    {
        if (tbl.ID == query.ID)
        {
            bool changed = false;
            if (tbl.Prop1 != query.Prop1)
            {
                tbl.Prop1 = query.Prop1;
                changed = true;
            }
            if (tbl.Prop2 != query.Prop2)
            {
                tbl.Prop2 = query.Prop2;
                changed = true;
            }

            if (changed)
                await Context.SaveChangesAsync();
        }
    }
}

There are 10 properties in total in the class, but even if all 10 of them differ I only have to update 2 properties, the rest can stay the same. So to summarize, my question is; Is there a better way to update these 2 properties? Something other than a bulky series of if statements and foreach loops? Any info on straight up inserting would be appreciated too, thanks very much!

Upvotes: 0

Views: 961

Answers (1)

Johan Bennink
Johan Bennink

Reputation: 53

EF uses an internal ChangeTracker. This means that when you change a property of an entity that is being tracked (you queried the lists using a DbSet on the Context) it will marked as "Changed" in the ChangeTracker. This is used by the SaveChangesAsync to determine what to do, ie. insert of update and what fields need to be updated. Second, this ChangeTracker is smart enough to detect that when you set a property to the same value it already has it won't be marked as a Change. Also with this ChangeTracker there is no need to call SaveChangesAsync after every change. You can call it at the end of the loop.

foreach (var tbl in Table_List)
{
    foreach (var query in SQL_Query)
    {
        if (tbl.ID == query.ID)
        {
            tbl.Prop1 = query.Prop1;
            tbl.Prop2 = query.Prop2;
        }
    }
}
await Context.SaveChangesAsync();

Upvotes: 1

Related Questions