批处理 Entity Framework 查询以提高效率
Batching Entity Framework queries for more efficiency
如果我有下面的代码片段在每个循环中查询数据库,有没有办法通过 运行 查询一次并传入列表或集合来提高效率?
using (var dbContext = new YogabandyContext(ybDatabaseConnectionString))
{
foreach (StripeBalanceTransaction transaction in balanceTransactions)
{
var profileCharge = dbContext.Charges.Where(i => i.BalanceTransactionId == transaction.Id).FirstOrDefault();
if (profileCharge == null)
{
// do some error work
}
else
{
profileCharge.PayoutStatus = PayoutStatus.Succeeded;
profileCharge.PayoutId = payoutId;
profileCharge.PayoutObjectResponse = stripeEvent.StripeResponse.ObjectJson;
}
}
dbContext.SaveChanges();
}
您可以重构此方法。只会对数据库执行两次查询,而不是 balanceTransactions.Count + 1
次:
var ids = balanceTransactions.Select(x => x.Id).ToList();
//first query
var profileCharges = dbContext.Charges
.Where(x => ids.Contains(x.BalanceTransactionId).ToList();
var existedIds = profileCharges.Select(x => x.BalanceTransactionId).ToList();
var notExisted = balanceTransactions.Where(x => !existedIds.Contains(x.Id)).ToList()
foreach(var transaction in notExisted)
{
//do some error work
}
profileCharges.ForEach(x =>
{
x.PayoutStatus = PayoutStatus.Succeeded;
x.PayoutId = payoutId;
x.PayoutObjectResponse = stripeEvent.StripeResponse.ObjectJson;
})
//second query
dbContext.SaveChanges();
如果我有下面的代码片段在每个循环中查询数据库,有没有办法通过 运行 查询一次并传入列表或集合来提高效率?
using (var dbContext = new YogabandyContext(ybDatabaseConnectionString))
{
foreach (StripeBalanceTransaction transaction in balanceTransactions)
{
var profileCharge = dbContext.Charges.Where(i => i.BalanceTransactionId == transaction.Id).FirstOrDefault();
if (profileCharge == null)
{
// do some error work
}
else
{
profileCharge.PayoutStatus = PayoutStatus.Succeeded;
profileCharge.PayoutId = payoutId;
profileCharge.PayoutObjectResponse = stripeEvent.StripeResponse.ObjectJson;
}
}
dbContext.SaveChanges();
}
您可以重构此方法。只会对数据库执行两次查询,而不是 balanceTransactions.Count + 1
次:
var ids = balanceTransactions.Select(x => x.Id).ToList();
//first query
var profileCharges = dbContext.Charges
.Where(x => ids.Contains(x.BalanceTransactionId).ToList();
var existedIds = profileCharges.Select(x => x.BalanceTransactionId).ToList();
var notExisted = balanceTransactions.Where(x => !existedIds.Contains(x.Id)).ToList()
foreach(var transaction in notExisted)
{
//do some error work
}
profileCharges.ForEach(x =>
{
x.PayoutStatus = PayoutStatus.Succeeded;
x.PayoutId = payoutId;
x.PayoutObjectResponse = stripeEvent.StripeResponse.ObjectJson;
})
//second query
dbContext.SaveChanges();