Bug #80578 When using context.somedbset.AddOrUpdate(..., ...) the SQL generated is invalid
Submitted: 2 Mar 2016 1:25 Modified: 2 Aug 2016 6:31
Reporter: Michael Kane Email Updates:
Status: Duplicate Impact on me:
None 
Category:Connector / NET Severity:S1 (Critical)
Version:6.9.8 OS:Windows
Assigned to: CPU Architecture:Any
Tags: addorupdate, ConcurrencyCheck, EF6, entity framework, SQL

[2 Mar 2016 1:25] Michael Kane
Description:
When using EF6 6.9.8, the SQL generated by the DbSet<T>.AddOrUpdate method is invalid.

Consider you have a set of 5 things you want to ensure are in a table - like some seed data.

Consider you have a class that has the following
class Thing {
   ...
   [ConcurrencyCheck]
   [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
   public DateTime Version { get;set; }
   ...
   public string Name { get;set; }
}

Now, consider you are in the Configuration.Seed(...) method with the following
var thing1 = new Thing { Name = "ABC" };

context.Things.AddOrUpdate(e => e.Name, thing1);
context.SaveChanges();//succeeds the very first time!  Fails after that.

From the above, you'll find the following SQL was generated via the context.Database.Log delegate.

-- @gp1: '3/1/2016 5:17:11 PM' (Type = DateTime, IsNullable = false)
-- @gp2: '3/1/2016 5:17:11 PM' (Type = DateTime, IsNullable = false)
SET @gp1 = '3/1/2016 5:17:11 PM';
SET @gp2 = '3/1/2016 5:17:11 PM';

UPDATE `Things` SET  WHERE (`ID` = 1) AND (`Version` = @gp1);
SELECT
`Version`
FROM `Things`
 WHERE  row_count() > 0 and (`ID` = 1) AND (`Version` = @gp2)

Notice the UPDATE statement has a SET that is empty and then a WHERE clause - ... SET  WHERE ....  

It is expected either
1) The UPDATE SET is populated correctly when there are changes
2) The UPDATE is skipped for no changes.

How to repeat:
Please see attached solution for something ready to go.
1) Create new CLI project targeting .net 4.6.1
2) Add/update Nuget Package MySql.Data.Entity v6.9.8, EntityFramework v6.1.3
2a) Setup connection string for your context
3) Add new class Thing
4) Add DbSet<Thing> to a new context pointing at your connection string
PM> Enable-Migrations
5) In Configuration Seed method, try to AddOrUpdate your things and also setup the MySQL bits
6)
PM> add-migration init 
PM> update-database

7) Works
8) 
PM> update-database
9) Fails

Suggested fix:
Given the AddOrUpdate method did in-fact select each item, skip the UPDATE when the SET clause is empty or there were no changes detected for the entity.
[2 Aug 2016 6:31] Chiranjeevi Battula
Hello Michael Kane,

Thank you for the bug report.
This is most likely duplicate of Bug #73271, please see Bug #73271.

Thanks,
Chiranjeevi.
[17 Oct 2016 18:52] Arjun Yadav
Hi,

Thanks for solution however It would be great if you could also provide details on how and where to apply this patch. 

Thanks