我已经使用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)
}