实体框架更新具有相同子项的对象列表

时间:2017-06-12 15:25:12

标签: c# entity-framework-6

这不是我第一次遇到这个实体框架的问题,即更新2个对象,这些对象的列表中包含具有相同子对象的子对象。

此示例的典型结构是父对象,其中包含每个都有标记列表的子对象列表。即:

class Parent{ 
public virtual ICollection<Child> Childs{get ;set;}
}

class Child {
public virtual IColletion<Tag> Tags{get; set;}
}
class Tag{
public int Id {get; set;}
public string Text {get; set;}
}

当尝试在同一次运行中更新父对象及其子对象时,我似乎无法找到令人满意的解决方案来向实体框架说实体Tag可以复制。

我大部分时间都遵循这个结构来更新实体框架中有孩子的父母。 How to add/update child entities when updating a parent entity in EF

为了解决这个问题,我曾经对连接表Tag_To_Childs进行硬编码,并且只使用标记对象的id,这样实体框架就不会在重复的密钥问题中运行。无论如何,我很高兴知道是否有人知道这个问题更优雅的解决方案。

以下是我实际更新子对象和标签Lists

的方法
   public async Task<List<Child>> updateChilds(Parent entry, Parent existingParent)
// entry being the new version and existingParent the tracked Db version
            {
                if (existingParent != null)
                {

                    // Delete children
                    foreach (var existingChild in existingParent.Childs.ToList())
                    {
                        if (!entry.Charts.Any(c => c.ChildId== existingChild.ChildId))
                            _context.Childs.Remove(existingChild);
                    }
                    // Update and Insert children
                    foreach (var childentry in entry.Childs)
                    {
                        var existingChild = existingParent.Childs
                            .Where(c => c.ChildId== childentry.ChildId)
                            .SingleOrDefault();

                        if (existingChild != null)
                        // Update child
                        {
                            await updateChildTags(existingChild, childentry);
                            _context.Entry(existingChild).CurrentValues.SetValues(childentry);
                        }
                        else
                        {
                            // Insert child
                            var newChild = new Chart
                            {

                                Title = childentry.Title,
                                Order = childentry.Order
                            };
                            newChild = await updateChildTags(newChild, childentry);
                            existingParent.Childs.Add(newChild);
                        }
                    }
                    await _context.SaveChangesAsync();
                }
                return existingParent.Childs.ToList();
            }


            public async Task<Child> updateChartTypeQuestions(Child realBlock, Child entry)
            {

                //delete bad tags
                List<Tag> toRemove = new List<Tag>();
                foreach (var existingChild in realBlock.Tags.ToList())
                {
                    if (!entry.Tags.Any(c => c.TagId== existingChild.TagId))
                        toRemove.Add(existingChild);
                }
                //add new ones
                foreach (var toAdd in entry.Tags.ToList())
                {
                    if (!realBlock.Tags.Any(c => c.TagId== toAdd.TagId))
                    {
                        Tag tag = await _context.Tags.FirstOrDefaultAsync(c => c.TagId == toAdd.TagId);
                        realBlock.Tags.Add(tag);
                    }
                }

                foreach (var toR in toRemove)
                {
                    realBlock.Tags.Remove(toR);
                }
                //the save change is called by parent function
                return realBlock;
            }

此代码的问题是,如果2个子项具有相同的标记,则只会正确更新第二个子项,并且将从第一个子对象中删除该标记。

0 个答案:

没有答案