C# 强制实体框架在一次往返中更新多个记录。

C# 强制实体框架在一次往返中更新多个记录。,c#,entity-framework,linq,C#,Entity Framework,Linq,我必须在EF中更新多个记录,我想出了以下两种方法: 方法1:ExecuteSqlCommand(直接SQL) 方法2:Linq foreach: var ui = from userInfo in customDB.UserInfo join userMapping in customDB.IAMUserMapping on userInfo.UserID equals userMapping.fUserId join iamUser in customD

我必须在EF中更新多个记录,我想出了以下两种方法:

方法1:
ExecuteSqlCommand
(直接SQL)

方法2:Linq foreach:

var ui = from userInfo in customDB.UserInfo
     join userMapping in customDB.IAMUserMapping 
         on userInfo.UserID equals userMapping.fUserId
     join iamUser in customDB.IAMUser 
         on userMapping.IAMUser.IAMID equals iamUser.IAMID
     where iamUser.IAMID == IAMID
     select new
     {
         userInfo.UserID,
         iamUser.Email,
         iamUser.Phone
     };

foreach (var x1 in ui)
{
    var u = new UserInfo
    {
        UserID = x1.UserID,
        Email = x1.Email,
        Mobile = x1.Phone
    };
    customDB.UserInfo.Attach(u);
    var entry = customDB.Entry(u);
    entry.Property(e => e.Email).IsModified = true;
    entry.Property(e => e.Mobile).IsModified = true;
}
customDB.SaveChanges();
方法#1是最有效的,它生成一个SQL查询

方法#2在SQL Server方面同样有效,但它会生成更多到服务器的往返。1选择获取记录,然后为每个更新的记录更新1次

如果数据库中的任何内容发生更改,方法#2将给出编译时错误,而#1将给出运行时错误

在这种情况下,人们认为最好的实践是什么?
有什么办法可以两全其美呢

对于第一种方法,您可能面临的问题将更为关键,也更难解决,例如在重命名/重组实体时。编译时错误比运行时错误好得多,易于解决

另外,我不确定ExecuteSqlCommand方法是如何工作的,但看起来这段代码容易受到SQL注入的攻击。
因此,我将明确选择linq方法。

So的标记中有一个众所周知的错误,它会导致编号列表中的代码格式问题。我刚刚拒绝了一个更糟糕的编辑,所以我现在无法修复。我在帖子上看到了它,用前面的书写方法修复了它。最佳实践使这个问题在堆栈溢出时脱离主题(基于观点,很难回答,因为这取决于您权衡两种方法的利弊)。还有其他方法可以优化此查询吗?这是一个更好的问题,但即使这样,也有人可能会认为CodeReview更适合。问题更多的是这两种方法是否是最好的方法,或者是否有第三种方法严格来说更好。在这种情况下,您的第一种方法是最好的,尤其是当它涉及大量记录时。另一种方法是使用存储的Proc,其结果与第一个示例非常相似。只要使用参数,ExecuteSqlCommand是安全的。如果您使用探查器进行跟踪,则生成的SQL是相等的。我不同意这一点,但这更多是一个意见问题。在第2点,它是参数化的,因此没有sql注入的风险。在OPs示例中,代码甚至会传入一个
SqlParameter
实例来说明它。这取决于您需要什么,正如一些人回答的那样,您可以执行存储过程,现在如果您想要消耗大量数据,这很简单,您可以将其放在托管的后台,并在夜间运行,因为进行事务的人较少。但是,如果人们知道如何使用本机SqlConnection、SqlCommand等,您当然可以使用这些参数。
var ui = from userInfo in customDB.UserInfo
     join userMapping in customDB.IAMUserMapping 
         on userInfo.UserID equals userMapping.fUserId
     join iamUser in customDB.IAMUser 
         on userMapping.IAMUser.IAMID equals iamUser.IAMID
     where iamUser.IAMID == IAMID
     select new
     {
         userInfo.UserID,
         iamUser.Email,
         iamUser.Phone
     };

foreach (var x1 in ui)
{
    var u = new UserInfo
    {
        UserID = x1.UserID,
        Email = x1.Email,
        Mobile = x1.Phone
    };
    customDB.UserInfo.Attach(u);
    var entry = customDB.Entry(u);
    entry.Property(e => e.Email).IsModified = true;
    entry.Property(e => e.Mobile).IsModified = true;
}
customDB.SaveChanges();