EF延迟加载机制导致的更新数据的时候有的更新有的没更新问题的解决

最近在处理一个问题的时候遇到了EF延迟加载导致的问题。我有一组任务,任务数量不固定,要分配给组员,组员数量也不固定。分配的时候原则上是平均分配,但是实际中肯定有多余的,这多余的会分配给最后一个组员。代码是这样写的:

var query = new TaskService().Get(m => m.TaskMainIID == dto.taskmainiid && m.Director == AdminInfo.IID && m.GroupLeader == 0 && m.AdminId == 0).OrderBy(m => m.IID).ToList().AsQueryable();
string[] arr = dto.GroupAndOperator.Split(',');
int zuCount = arr.Length;  //获取小组或话务员的总数
int count = query.Count();   //获取待分配的记录总数
int number = count / zuCount; //取整
int remainder = count % zuCount;   //取余数

int skip = 0;
foreach (var item in arr)   //循环获取组或组员变化
{
//EventLog.WriteLog("item:" + item);
//EventLog.WriteLog("skip:" + skip);
var index = Array.IndexOf(arr, item);  //数组索引

var groupid = TextUtility.CutRight(item, item.Length - 1).ToInteger();
var zuUser = UserManager.Users.FirstOrDefault(m => m.GroupId == groupid && m.RoleLevel == 1);  //获取组长信息
if (zuUser != null)
{
//获取小组长编号
var zuiid = zuUser.IID;
IQueryable<Task> queryzu;
if(remainder>0&&index==(arr.Length-1))
{
    EventLog.WriteLog("zu last:" + item + "--"  + skip + "--" + (number + remainder));
    queryzu = query.Skip(skip).Take(number+remainder);  //获取number+remainder个任务
}
else
{
    EventLog.WriteLog("zu:" + item + "--" + skip + "--" + (number));
    queryzu = query.Skip(skip).Take(number);  //获取number个任务
}
string k = "";
foreach (var task1 in queryzu)  //获取的任务分配给小组长
{
    task1.GroupLeader = zuiid;  //改为组长编号
    new TaskService().Update(task1);
    k += task1.IID + "|";
}
EventLog.WriteLog(k);
}


skip +=number;

}


用var query = new TaskService().Get(m => m.TaskMainIID == dto.taskmainiid && m.Director == AdminInfo.IID && m.GroupLeader == 0 && m.AdminId == 0)读出所有的待分配的任务。

arr是获取的组员数组,然后循环读取组员,用任务总数整除组员数,就得出每个组员要分配的数量。最后一个组员,会把多余的分配给他。

这个过程中要多次用到query.Skip(skip).Take(number)来获取相应的任务记录,并且循环更新相应的Groupleader及adminid状态。弄好后用5个任务进行测试,在数据库中发觉更新的时候是跳着更新的,总有2条数据没更新到。于是用eventlog.writelog输出中间变量,发觉中间变量都符合预期。难道是因为query.Skip(skip).Take(number)有记忆功能。会自动记录跳过的条数,然后下次再使用query.skip会自动从上次查询的位置再向下查询?又觉得不像,因为分页查询就是使用的skip和take结合实现的,这每次跳过记录也是从第一条记录开始算的。为了检验是否是skip的问题导致。特意做了验证测试,发觉一切正常。会是什么导致的这个问题呢。反复思考原因,忽然想到会不会是EF延迟机制导致的此问题。按这个思路思考。在多次使用query.skip时,每次都是在skip的时候自数据库中查询记录。而我在循环的时候是更改了groupleader值的。而var query = new TaskService().Get(m => m.TaskMainIID == dto.taskmainiid && m.Director == AdminInfo.IID && m.GroupLeader == 0 && m.AdminId == 0) ,这个query每次查询是要根据groupleader筛选条件的。这一更改值,不符合条件了。下次query.skip就会少记录。这样就导致跳着更新的情况了。要避免这种情况,只有一次性把数据读取到内存中,下次不再从数据库中读取。实现这个要用到tolist,但是用了tolist就不能使用skip ,take这种方法了。于是我做了这样的修改:

var query = new TaskService().Get(m => m.TaskMainIID == dto.taskmainiid && m.Director == AdminInfo.IID && m.GroupLeader == 0 && m.AdminId == 0).OrderBy(m => m.IID).ToList().AsQueryable();

这样query既保证了一次性读取到了内存中,又保证了可以使用skip及take方法读取数据。经过测试,可以正确更新数据了。

猜你喜欢

转载自blog.csdn.net/sxf359/article/details/78293370