C# LINQ到实体事务性能问题 公共无效寄存器(十进制groupId、十进制deptId、十进制employeeId) { 使用(EmployeeEntities db=new EmployeeEntities()) { 使用(TransactionScope作用域=新TransactionScope(TransactionScopeOption.Required,新TransactionOptions{IsolationLevel=IsolationLevel.Snapshot})) { var course=db.Courses.Where(s=>s.GroupId==GroupId&&s.DepartmentId==deptId.ToList(); foreach(过程中的var项目) { var filledSeats=db.courserregistrations.Count(c=>c.CourseId==item.CourseId&&c.DepartmentId==deptId&(c.canceleredfl==null | | c.canceleredfl==false)); 如果(item.allocatedSeats s.GroupId==item.GroupId)。选择(s=>s.GroupName.FirstOrDefault()); } 如果(!db.CourseRegistrations.Any(s=>s.EmployeeId==EmployeeId&&s.CourseId==item.CourseId&&s.CancelledFl==false | | s.CancelledFl==null))) { var courseRegister=新courseregistation(); db.CourseRegistrations.Add(courseRegister); courseRegister.CourseId=item.CourseId; courseRegister.EmployeeId=员工ID; courseRegister.CreatedBy=1; courseRegister.CreatedDt=DateTime.Now; courseRegister.RecordVa=1; item.Filled座椅=item.Filled座椅+1; } } db.SaveChanges(); scope.Complete(); } } }
考虑上面的代码。当请求被发送到C# LINQ到实体事务性能问题 公共无效寄存器(十进制groupId、十进制deptId、十进制employeeId) { 使用(EmployeeEntities db=new EmployeeEntities()) { 使用(TransactionScope作用域=新TransactionScope(TransactionScopeOption.Required,新TransactionOptions{IsolationLevel=IsolationLevel.Snapshot})) { var course=db.Courses.Where(s=>s.GroupId==GroupId&&s.DepartmentId==deptId.ToList(); foreach(过程中的var项目) { var filledSeats=db.courserregistrations.Count(c=>c.CourseId==item.CourseId&&c.DepartmentId==deptId&(c.canceleredfl==null | | c.canceleredfl==false)); 如果(item.allocatedSeats s.GroupId==item.GroupId)。选择(s=>s.GroupName.FirstOrDefault()); } 如果(!db.CourseRegistrations.Any(s=>s.EmployeeId==EmployeeId&&s.CourseId==item.CourseId&&s.CancelledFl==false | | s.CancelledFl==null))) { var courseRegister=新courseregistation(); db.CourseRegistrations.Add(courseRegister); courseRegister.CourseId=item.CourseId; courseRegister.EmployeeId=员工ID; courseRegister.CreatedBy=1; courseRegister.CreatedDt=DateTime.Now; courseRegister.RecordVa=1; item.Filled座椅=item.Filled座椅+1; } } db.SaveChanges(); scope.Complete(); } } },c#,sql-server,performance,entity-framework,asp.net-web-api,C#,Sql Server,Performance,Entity Framework,Asp.net Web Api,考虑上面的代码。当请求被发送到ASP.NET WebAPI控制器时,它是一个最终被调用的函数 该函数只需在检查座位可用性后将员工注册到课程。大约200名员工将同时注册课程 我正在为每个事务使用快照隔离 我的问题在于性能。它是慢的。有时它会超时 我的问题是为什么?我的代码哪一部分出错了?在所有这些交易中到底发生了什么?什么等待还是什么锁定?在for循环中有多个对数据库的调用,这意味着您将消耗db请求延迟2倍于course.length时间的总成本,而您只需要消耗一次,可能两次。查看是否可以将db.
ASP.NET WebAPI
控制器时,它是一个最终被调用的函数
该函数只需在检查座位可用性后将员工注册到课程。大约200名员工将同时注册课程
我正在为每个事务使用快照隔离
我的问题在于性能。它是慢的。有时它会超时
我的问题是为什么?我的代码哪一部分出错了?在所有这些交易中到底发生了什么?什么等待还是什么锁定?在for循环中有多个对数据库的调用,这意味着您将消耗db请求延迟2倍于course.length时间的总成本,而您只需要消耗一次,可能两次。查看是否可以将
db.courserregistrations
中的必要数据带到循环之外,这可能是与课程数据关联的同一查询的一部分。然后,您可以在内存中的循环中执行操作,这将快几个数量级。如果您正在执行许多更新/插入,EF默认情况下会自动跟踪这些更改,如果您正在更新许多记录,这将严重影响性能。为了帮助实现这一点,您可以在批量更新之前关闭该功能,然后在完成更新后再次打开该功能
public void Register(decimal groupId, decimal deptId, decimal employeeId)
{
using (EmployeeEntities db = new EmployeeEntities())
{
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.Snapshot }))
{
var course = db.Courses.Where(s => s.GroupId == groupId && s.DepartmentId == deptId).ToList();
foreach (var item in course)
{
var filledSeats = db.CourseRegistrations.Count(c => c.CourseId == item.CourseId && c.DepartmentId == deptId && (c.CancelledFl == null || c.CancelledFl == false));
if (item.AllotedSeats <= filledSeats)
{
throw new Exception("Sorry! Seats are not available for " + db.Groups.Where(s => s.GroupId == item.GroupId).Select(s => s.GroupName).FirstOrDefault());
}
if (!db.CourseRegistrations.Any(s => s.EmployeeId == employeeId && s.CourseId == item.CourseId && (s.CancelledFl == false || s.CancelledFl == null)))
{
var courseRegister = new CourseRegistration();
db.CourseRegistrations.Add(courseRegister);
courseRegister.CourseId = item.CourseId;
courseRegister.EmployeeId = employeeId;
courseRegister.CreatedBy = 1;
courseRegister.CreatedDt = DateTime.Now;
courseRegister.RecordVa = 1;
item.FilledSeats = item.FilledSeats + 1;
}
}
db.SaveChanges();
scope.Complete();
}
}
}
try
{
db.Configuration.AutoDetectChangesEnabled = false;
//loop through your updates here
}
finally
{
db.Configuration.AutoDetectChangesEnabled = true;
}
db.SaveChanges();