Ignore duplicate key insert with Entity Framework

后端 未结 5 465
遇见更好的自我
遇见更好的自我 2020-12-29 03:36

I\'m using ASP.NET MVC4 with Entity Framework Code First. I have a table called \"users\", with primary key \"UserId\". This table may have 200,000+ entries.

I need

5条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-29 04:26

    You can filter out the existing users with one query

    foreach(User user in NewUsers.Where(us => !dbcontext.Users.Any(u => u.userId == us.userId)))
    {
        dbcontext.Users.Add(user);
    }
    dbcontext.SaveChanges();
    

    EDIT:

    As pointed out in the comments the proposal above will result in an sql call for each element in the NewUsers collection. I could confirm that with SQL Server Profiler.

    One intresting result of the profiling is the somewhat wierd sql generated by EF for each item(Model names are different than in the OP, but the query is the same):

    exec sp_executesql N'SELECT 
    CASE WHEN ( EXISTS (SELECT 
        1 AS [C1]
        FROM [dbo].[EventGroup] AS [Extent1]
        WHERE [Extent1].[EventGroupID] = @p__linq__0
    )) THEN cast(1 as bit) WHEN ( NOT EXISTS (SELECT 
        1 AS [C1]
        FROM [dbo].[EventGroup] AS [Extent2]
        WHERE [Extent2].[EventGroupID] = @p__linq__0
    )) THEN cast(0 as bit) END AS [C1]
    FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]',N'@p__linq__0 int',@p__linq__0=10
    

    Quite a nice piece of code to do the job of a simple one-liner.

    My point of view is that writing nice and readable declarative code and let the compiler and optimizer do the dirty job is a great attitude. This is one of the cases when the result of such a style is surprising and you have to go dirty.

提交回复
热议问题