【问题标题】:Entity Framework many-to-many generic Update实体框架多对多通用更新
【发布时间】:2015-12-18 20:46:11
【问题描述】:

我正在尝试使用 EF6 实现通用的多对多更新方法。 每次我尝试更新导航属性时,都会出现异常:

“违反PRIMARY KEY约束'PK_dbo.Classes'。无法插入 对象“dbo.Classes”中的重复键。重复键值为 (698d5483-eb48-4d7e-84e7-a9f95a243d3d)。\r\n语句已 终止。”

我该如何解决?

public void Update(T entity, params Expression<Func<T, IEnumerable>>[] navProps)
{
    using (var context = new Context())
    {
        T foundEntity = context.Set<T>().Find(entity.Id);
        var entry = context.Entry(foundEntity);
        entry.CurrentValues.SetValues(entity);

        foreach (var prop in navProps)
        {
            string memberName;
            var member = prop.Body as MemberExpression;

            if (member != null)
            {
                memberName = member.Member.Name;
            }
            else
            {
                throw new Exception();
            }

            var collection = entry.Collection(memberName);
            collection.Load();
            collection.CurrentValue = typeof(T).GetProperty(memberName).GetValue(entity);
        }

        context.SaveChanges();
    }
}

【问题讨论】:

  • 您是否删除了一些孩子,添加了一些,编辑了一些?
  • 是的,我添加了子实体。
  • 您需要更新您的对象图。您应该将所有已删除、添加和修改的子实体引入上下文,这不是一项简单的任务。您可能会发现此step by step answer 很有帮助。
  • 有一个工具可以帮助您实现目标:GraphDiff。

标签: c# entity-framework generics entity-framework-6


【解决方案1】:

我终于找到了通用多对多更新的解决方案

 public void Update(Guid id, T record)
        {
            using (var context = new FortisDataStoreContext(_client, _user))
            {
                var set = context.Set<T>().AsQueryable();

                foreach (var x in GetNavigationProperties(context, record))
                {
                    foreach (var xx in x.PropertyType.GetGenericArguments())
                    {
                        set = set.Include(x.Name);
                    }
                }

                var entry = set.FirstOrDefault(x => x.Id == id && x.IsClosed == false);
                context.Entry(entry).CurrentValues.SetValues(record);

                foreach (var x in GetNavigationProperties(context, record))
                {
                    if(x.PropertyType.GetGenericArguments().Count() > 0)
                    {
                        var genericType = x.PropertyType.GenericTypeArguments[0];
                        var newValues = (IList)x.GetValue(record, null) ?? new object[0];
                        var genericList = CreateList(genericType);
                        foreach (var item in newValues)
                        {
                            var ident = item.GetType().GetProperty("Id").GetValue(item, null);
                            var obj = context.Set(genericType).Find(ident);
                            genericList.Add(obj);
                        }
                        context.Entry(entry).Collection(x.Name).CurrentValue = genericList;
                    }
                }

                context.SaveChanges();
            }
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-01
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多