简体   繁体   English

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

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

I want to swap items to re order. 我想交换物品以重新订购。 Reorder index is primary key so I can not edit it. 重新排序索引是主键,因此我无法对其进行编辑。 So what I am doing: 所以我在做什么:

  1. I am searching items with name and cloned it to another object. 我正在搜索具有名称的项目并将其克隆到另一个对象。
  2. I am also searching previous item on that with key found on case 1. and cloned it to an object. 我还使用案例1中找到的密钥在该项目上搜索了上一个项目,并将其克隆到一个对象中。
  3. I deleted both the search items from DB. 我从数据库中删除了两个搜索项。
  4. Insert New replaced item with previous key and change previous cloned item key to a random no. 用上一个关键字插入新替换的项目并将之前克隆的项目密钥更改为随机编号。 add to DB. 添加到数据库。
  5. During search when this preivous item through name in loop it key change from clone and add to db. 在搜索过程中,通过名称循环此重要项目时,它会将密钥从clone更改并添加到db。

Its working when First Compile. 首次编译时可正常工作。 But when I reorder again in list then it throws error in Conflicting Primary keys in both case Attach() and Remove() . 但是,当我再次在列表中重新排序时,在Attach()Remove()两种情况下,它在“ Conflicting Primary keys中都会引发错误。

Code is as follows 代码如下

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

The thing is that SQL server autoincrements the primary keys even though you are deleting records. 事实是,即使您要删除记录, SQL server也会自动增加主键。 Check this post, it will help you out in how to reset back those primary keys. 检查这篇文章,它将帮助您解决如何重置这些主键的问题。 That's why you are getting exceptions regarding primary key conflicts. 这就是为什么您会遇到有关主键冲突的异常的原因。

However, that is a short term solution and I would not recommend it. 但是,这是一个短期解决方案,我不建议这样做。 I would definitely redesign your solution. 我一定会重新设计您的解决方案。 At the end, you just want a Display Order for the items that you are swapping. 最后,您只需要交换订单的显示顺序。

I would create a new column in the table called DisplayOrder that would add values from 1 to n every time a record is added. 我将在名为DisplayOrder的表中创建一个新列,该列将在每次添加记录时将值从1添加到n。 And, then I would just call OrderBy(i => i.DisplayOrder) . 然后,我将只调用OrderBy(i => i.DisplayOrder) And, at the end, if you really need to swap values (change their order), I would create a new function called SwapValues(ProjectTaskA, projectTaskB) that would change their display order. 并且,最后,如果您确实需要交换值(更改其顺序),我将创建一个名为SwapValues(ProjectTaskA, projectTaskB)的新函数,该函数将更改其显示顺序。 Or, if you really want to make it even better, you could create something called SwapValues(ProjectTask, moveDown, numberOfSteps) with the object in question, the number of steps that would have to go until finding the object to be swapped with and a direction, up or down. 或者,如果您真的想做得更好,可以使用相关对象创建一个名为SwapValues(ProjectTask, moveDown, numberOfSteps)东西SwapValues(ProjectTask, moveDown, numberOfSteps)找到要交换的对象之前必须执行的步骤数以及方向,向上或向下。

These are just a couple of ideas of what you could do. 这些只是您可以做什么的一些想法。 I hope they help you. 希望他们能对您有所帮助。

After 4 days of fighting with Primery Key voilation... I found simple solution 经过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