使用EF6交换列表中的项目,使用主键交换c#

时间:2016-05-23 14:48:53

标签: c# asp.net asp.net-mvc entity-framework

我想将商品换成重新订购。重新排序索引是主键,因此我无法编辑它。所以我在做什么:

  1. 我正在搜索带有名字的项目并将其克隆到另一个对象。
  2. 我也在用案例1中找到的密钥搜索上一个项目,并将其克隆到一个对象。
  3. 我从DB中删除了这两个搜索项目。
  4. 使用上一个键插入新替换的项目,并将以前克隆的项目键更改为随机编号。添加到DB。
  5. 在搜索过程中,当这个特殊项目通过循环中的名称时,密钥会从克隆更改并添加到数据库。
  6. 它在First Compile时工作。但是当我再次在列表中重新排序时,在Conflicting Primary keysAttach()这两种情况下Remove()都会抛出错误。

    代码如下

    foreach (var item in items)
    {
        var task = db.ProjectTasks.Where(wh => wh.ProjectID == item.projectID && wh.TaskDesc==item.taksName).FirstOrDefault();
        var oldTask = db.ProjectTasks.Where(wh => wh.ProjectID == item.projectID && wh.TaskID == item.taskID).FirstOrDefault();
        if (oldTask != null)
        {
            //db.ProjectTasks.Attach(oldTask);
            db.ProjectTasks.Remove(oldTask);
            //db.SaveChanges();
        }
    
    
      //  var cloneTask = task;   //Cloned task to inser same ater delete
    
    
        var taskClone1 = new ProjectTask { 
            ActualManHrs=task.ActualManHrs,
            AFDate=task.AFDate,
            ASDate=task.ASDate,
            ConDate=task.ConDate,
            DaysComplete=task.DaysComplete,
            DaysRemaining=task.DaysRemaining,
            Duration=task.Duration,
            DurationActual=task.DurationActual,
            EFDate=task.EFDate,
            ESDate=task.ESDate,
            orderIndex=task.orderIndex,
            PercentComplete=task.PercentComplete,
            PlannedManHrs=task.PlannedManHrs,
            PriorTask=task.PriorTask,
            ProjectID=task.ProjectID,
            ProjectMaster=task.ProjectMaster,
            Remarks=task.Remarks,
            ResourceCenter=task.ResourceCenter,
            TaskDesc=task.TaskDesc,
            TaskGroup=task.TaskGroup,
            TaskID=item.taskID,
            TaskStatus=task.TaskStatus,
            WorkingDays=task.WorkingDays
    
        };
    
        var swap1 = new List<ProjectTask>();
        swap1.Add(taskClone1);
    
        ProjectTask oldTaskDetails = null;
        if (oldTask != null)
        {
            oldTaskDetails = new ProjectTask
            {
                ActualManHrs = oldTask.ActualManHrs,
                AFDate = oldTask.AFDate,
                ASDate = oldTask.ASDate,
                ConDate = oldTask.ConDate,
                DaysComplete = oldTask.DaysComplete,
                DaysRemaining = oldTask.DaysRemaining,
                Duration = oldTask.Duration,
                DurationActual = oldTask.DurationActual,
                EFDate = oldTask.EFDate,
                ESDate = oldTask.ESDate,
                orderIndex = oldTask.orderIndex,
                PercentComplete = oldTask.PercentComplete,
                PlannedManHrs = oldTask.PlannedManHrs,
                PriorTask = oldTask.PriorTask,
                ProjectID = oldTask.ProjectID,
                ProjectMaster = oldTask.ProjectMaster,
                Remarks = oldTask.Remarks,
                ResourceCenter = oldTask.ResourceCenter,
                TaskDesc = oldTask.TaskDesc,
                TaskGroup = oldTask.TaskGroup,
                TaskID = oldTask.TaskID,
                TaskStatus = oldTask.TaskStatus,
                WorkingDays = oldTask.WorkingDays
            };
        }
    
        var swap2 = new List<ProjectTask>();
        swap2.Add(oldTaskDetails);
    
        if(task!=null) //Check Nll or not
        {
            db.ProjectTasks.Remove(task); //2nd time on ward Primary key voilation
            db.SaveChanges();
    
            db.ProjectTasks.AddRange(swap1); //2nd time on ward Primary key voilation 
    
            if (oldTaskDetails != null)
            {
                oldTaskDetails.TaskID = Guid.NewGuid().ToString().Substring(0, 4);                                
                db.ProjectTasks.AddRange(swap2);                                
            }
        }
        //db.SaveChanges();
    }
    

2 个答案:

答案 0 :(得分:0)

即使你要删除记录,问题就是SQL server自动增加主键。查看this帖子,它将帮助您重置如何重置这些主键。这就是为什么你得到关于主键冲突的例外。

然而,这是一个短期解决方案,我不推荐它。我肯定会重新设计你的解决方案。最后,您只需要为要交换的项目显示订单。

我会在名为DisplayOrder的表中创建一个新列,每次添加一条记录时都会添加从1到n的值。然后,我会打电话给OrderBy(i => i.DisplayOrder)。而且,最后,如果你真的需要交换值(改变它们的顺序),我会创建一个名为SwapValues(ProjectTaskA, projectTaskB)的新函数来改变它们的显示顺序。或者,如果你真的想让它变得更好,你可以创建一个名为SwapValues(ProjectTask, moveDown, numberOfSteps)的东西,其中包含有问题的对象,在查找要交换的对象和方向之前必须执行的步骤数,向上或者下来。

这些只是您可以做的几点想法。我希望他们帮助你。

答案 1 :(得分:0)

与Primery Key发声后4天的战斗......我找到了简单的解决方案

var projectID = items.FirstOrDefault().projectID;
                    var group=items.FirstOrDefault().sourceGroup;

                    //Loop through changable item
                    foreach(var item in items)
                    {
                    checkPrimeryKey: //return back after changin duplicate item taskID
                        var checkDuplicate = db.ProjectTasks.Where(wh => wh.ProjectID == projectID && wh.TaskID == item.taskID).FirstOrDefault();
                        if (checkDuplicate == null) //If not Duplicate found
                        {
                            string sql = "update ProjectTasks set taskID='" + item.taskID + "' where projectID=" + projectID + " and TaskDesc='" + item.taksName + "'";
                            db.Database.ExecuteSqlCommand(sql);
                        }
                        else //If duplicate found change its task ID and return back to Step:1
                        {
                            string sql = "update ProjectTasks set taskID='" + Guid.NewGuid().ToString().Substring(0, 4) + "' where projectID=" + projectID + " and TaskDesc='" + checkDuplicate.TaskDesc + "'";
                            db.Database.ExecuteSqlCommand(sql);
                            goto checkPrimeryKey;
                        }
                    }
                    db.SaveChanges();