繁体   English   中英

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

[英]Swap items in a list using EF6 and c# with primary keys

我想交换物品以重新订购。 重新排序索引是主键,因此我无法对其进行编辑。 所以我在做什么:

  1. 我正在搜索具有名称的项目并将其克隆到另一个对象。
  2. 我还使用案例1中找到的密钥在该项目上搜索了上一个项目,并将其克隆到一个对象中。
  3. 我从数据库中删除了两个搜索项。
  4. 用上一个关键字插入新替换的项目并将之前克隆的项目密钥更改为随机编号。 添加到数据库。
  5. 在搜索过程中,通过名称循环此重要项目时,它会将密钥从clone更改并添加到db。

首次编译时可正常工作。 但是,当我再次在列表中重新排序时,在Attach()Remove()两种情况下,它在“ Conflicting Primary keys中都会引发错误。

代码如下

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();
}

事实是,即使您要删除记录, SQL server也会自动增加主键。 检查这篇文章,它将帮助您解决如何重置这些主键的问题。 这就是为什么您会遇到有关主键冲突的异常的原因。

但是,这是一个短期解决方案,我不建议这样做。 我一定会重新设计您的解决方案。 最后,您只需要交换订单的显示顺序。

我将在名为DisplayOrder的表中创建一个新列,该列将在每次添加记录时将值从1添加到n。 然后,我将只调用OrderBy(i => i.DisplayOrder) 并且,最后,如果您确实需要交换值(更改其顺序),我将创建一个名为SwapValues(ProjectTaskA, projectTaskB)的新函数,该函数将更改其显示顺序。 或者,如果您真的想做得更好,可以使用相关对象创建一个名为SwapValues(ProjectTask, moveDown, numberOfSteps)东西SwapValues(ProjectTask, moveDown, numberOfSteps)找到要交换的对象之前必须执行的步骤数以及方向,向上或向下。

这些只是您可以做什么的一些想法。 希望他们能对您有所帮助。

经过4天与Primery Key对抗的战斗...我找到了简单的解决方案

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();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM