从.net c#应用程序循环中正确有效地更新sql server数据库表中的数百条记录



我已经使用Entity Framework 6一段时间了,通常一次更新一条记录。

但是,我需要遍历所有用户,300-1000个用户

更新数据库中的几列是否会非常低效和缓慢。使用EF6.x?我应该使用ADO.NET,还是通过网络发送某种对象,进行批量更新??

目前我像这个一样更新

rpmuser.usr_id = user;
rpmuser = db.rpm_usr.Find(rpmuser.usr_id);
rpmuser.lst_pwd_chg_dtm = dateTime;
rpmuser.cre_dtm = dateTime;
rpmuser.usr_pwd = hash;
rpmuser.salt = salt;
db.SaveChanges();

所以本质上,如果我绕过其他用户,那可以吗?我还能用批量更新做什么?

for( ....  ) {
// different user id 
// all the other needed poco model changes above... etc.
// db.SaveChanges()
}

您可以使用以下代码对此进行测试:

static void Main(string[] args)
{
CreateAndSeedTheDatabase(); // Step 1: run this
//UpdateAllOfTheProducts(); // Step 2: Comment out the above line and uncomment and run this line
}
static void CreateAndSeedTheDatabase()
{
Context context = new Context();
context.Database.Initialize(true);
Product product;
for (int i = 0; i < 1000; i++)
{
product = new Product() { ProductId = i, Name = "Product" + i };
context.Products.Add(product);
}
context.SaveChanges();
}
static void UpdateAllOfTheProducts()
{
Context context = new Context();
Product[] products = context.Products.ToArray();
foreach (Product product in products)
{
product.Name = product.ProductId + "Product";
}
context.SaveChanges();
}
public class Context : DbContext
{
public Context()
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<Context>());
}
public DbSet<Product> Products { get; set; }
}
public class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
}

}

要正确高效地更新数百条记录,需要尽可能减少数据库往返。

在您的案例中,有两种方法可以使重数据库往返

查找方法

对于每一个需要更新的用户,都需要进行数据库往返。有多种方法可以快速减少这种情况。

  • 加载所有用户,并使用关键字为"usr_id"的字典只进行一次数据库往返(如果数据库不包含数百万用户,则运行良好!)

  • 创建一个包含所有"usr_id"的列表,并使用Contains Methods 一次检索所有用户

示例:

// Work well if the database doesn't contain to much users
var userDict = db.rpm_usr.ToList().ToDictionary(x => x.usr_id);

// Be careful, the list cannot contains more than 2099 items (SQL Parameters limit = 2100)
var userDict = db.rpm_usr.Where(x => ids.Contains(x.usr_id)).ToDictionary(x => x.usr_id);

在这两种解决方案中,只执行一次数据库往返,并且可以非常有效地从字典中检索用户。

保存更改方法

SaveChanges方法为每个要更新的记录执行数据库往返。因此,如果您更新1000个用户,将进行1000次数据库往返,这是非常缓慢的。

免责声明:我是项目实体框架扩展的所有者

该项目允许执行BulkSaveChanges和BulkUpdate以显著提高性能:

for( ....  ) {
// different user id 
// all the other needed poco model changes above... etc.
db.BulkSaveChanges()
}
for( ....  ) {
// different user id 
// all the other needed poco model changes above... etc.
db.BulkUpdate(users)
}

最新更新