更新许多到许多导航属性的实体框架6,改变不被保存 [英] Updating many-to-many navigation property in Entity Framework 6, changes not being saved

查看:161
本文介绍了更新许多到许多导航属性的实体框架6,改变不被保存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在拉我的头发约2天了,因为我根本无法EF保存更改,每当我加很多一对多的实体到现有的实体。

我的结构朴素简单:

  • 我有一个名为表,它有一个ID(主,身份),以及其他一些字符串字段

  • 名为关键字 A表的ID(小学,标识)和一个字符串字段名为

  • PersonKeywordRelation ,用 PERSONID KeywordId 字段

当我已生成我的实体(数据库第一),我得到一个类,与的ICollection<关键字> - 都好,工作正常

当我尝试保存现有,关键字的修改清单的问题就出现了。只有标量属性(串)被保存,而不是我的关键字!

  • 我已经试过禁用延迟加载,没有任何影响。
  • 在我再次尝试加载从数据库中每个关键字,没有任何影响。
  • 在我尝试加载的所有关键字插入上下文看,这将有助于EF检测更改,事实并非如此。

我是pretty的肯定,我不是谁都有过这样的问题只有一个,(其实我完全相信,因为我看到的在这里一对夫妇的问题已经,就同一问题,但我不能找到工作的答案...),多为旧版本的EF,这是另一个很好的理由,为什么我开始了另一个问题:没有什么改变了这一切可以解决此问题在所有

下面是我的code,做的人的更新(和创造)。你会注意到我的努力于使EF保存相应的更改。

 公共无效SavePersons(IList的<人>人)
    {
        //创建一个EF上下文
        使用(VAR CTX =新MyDbEntities())
        {
            的foreach(VAR人的人)
            {
                // 连接
                ctx.Persons.Attach(人);

                //插入或更新?
                ctx.Entry(人).State = person.Id == 0? EntityState.Added:EntityState.Modified;

                //获取当前的关键字从实体结算前
                VAR关键字=新的名单,其中,关键字>(person.Keywords);

                从实体//清除关键字,因此我们可以添加新鲜的,有希望
                // EF将有一个更简单的时间处理这个..
                person.Keywords.Clear();

                //添加关键字
                keywords.ForEach(KW =>
                {
                    ctx.Keywords.Attach(KW);
                    ctx.Entry(KW).State = EntityState.Modified;
                    person.Keywords.Add(KW);
                });
            }

            // 保存
            ctx.SaveChanges();
        }
    }
 

解决方案

最后......最后,我可以休息了!我找到了解决办法!这不是一个pretty的一个,但它的作品!

这里的code - 共享是关怀

这肯定是我最后一次将与实体框架。造成更多的痛苦和放大器;痛苦不是很好。

 公共无效SavePersons(IList的<人>人)
    {
        //创建一个EF上下文
        使用(VAR CTX =新MyDbEntities())
        {
            //迭代
            的foreach(VAR人的人)
            {
                //获取当前关键字
                VAR关键字=新的名单,其中,关键字>(person.Keywords).ToList();

                //从数据库提取人(如果它不是一个新的条目)。必须使用包含,否则它不工作。
                VAR newPerson = ctx.Persons
                                       .INCLUDE(关键字)
                                       .FirstOrDefault(S => s.Id == person.Id)?人;

                //对象的清除关键字,否则EF将它们插入..傻了。
                newPerson.Keywords.Clear();

                //插入或更新?
                ctx.Entry(newPerson).State = newPerson.Id == 0? EntityState.Added:EntityState.Modified;

                //将新标量值
                如果(newPerson.Id!= 0)
                {
                    person.Id = newPerson.Id;
                    ctx.Entry(newPerson).CurrentValues​​.SetValues​​(人);

                }

                //遍历所有关键字
                的foreach(在ctx.Keywords VAR千瓦)
                {
                    //如果当前千瓦存在于我们的列表中,添加
                    //  - 如果不是,请从DB的关系。
                    如果(keywords.Any(K => k.Id == kw.Id))
                    {
                        //ctx.Entry(kw).State = EntityState.Unchanged;
                        ctx.Keywords.Attach(KW);
                        newPerson.Keywords.Add(KW);
                    }
                    其他
                        newPerson.Keywords.Remove(KW);
                }
            }

            // 保存
            ctx.SaveChanges();

        }
    }
 

I've been pulling my hair out for about 2 days now, as I simply cannot get EF to save changes whenever I add a many-to-many entity to an existing entity.

My structure is plain simple:

  • I have a table called Person, it has an ID (Primary, identity), and a few other string fields

  • A table called Keyword with an ID (Primary, identity) and a string field called Value

  • and a PersonKeywordRelation, with a PersonId, and a KeywordId field

When I have generated my entities (Database first), I get a class Person, with an ICollection<Keyword> - all good, works as expected.

The problem arises when I try to save an existing Person, with a modified list of keywords. Only the scalar properties (strings) are saved, not my keywords!

  • I've tried disabling Lazy Loading, no effect.
  • I tried loading each individual keyword from the database again, no effect.
  • I tried loading all keywords into the context to see if that would help EF detect changes, it didn't.

I am pretty sure I'm not the only one who have had this problem, (in fact I am entirely sure as I have seen a couple questions on here already, on the same subject, yet I am unable to find a working answer...), mostly for older versions of EF, which is another good reason as to why I started yet another question: Has nothing changed that addresses this issue at all?

Here is my code that does the updating (and creation) of persons. You'll notice my attempt on making EF save changes accordingly.

    public void SavePersons(IList<Person> persons)
    {
        // Create a EF Context
        using (var ctx = new MyDbEntities())
        {
            foreach (var person in persons)
            {
                // Attach
                ctx.Persons.Attach(person);

                // Insert or update?
                ctx.Entry(person).State = person.Id == 0 ? EntityState.Added : EntityState.Modified;

                // Get current keywords before clearing from entity
                var keywords = new List<Keyword>(person.Keywords);

                // Clear keywords from entity, so we can add fresh ones, hopefully
                // EF will have an easier time handling this..
                person.Keywords.Clear();

                // Add keywords
                keywords.ForEach(kw =>
                {
                    ctx.Keywords.Attach(kw);
                    ctx.Entry(kw).State = EntityState.Modified;
                    person.Keywords.Add(kw);
                });            
            }

            // Save
            ctx.SaveChanges();
        }
    }

解决方案

Finally.. Finally I can rest! I found the solution! It's not a pretty one, but it works!

Here's the code - sharing is caring.

This is definitely the last time I will work with Entity Framework. Causes more pain & agony than good.

    public void SavePersons(IList<Person> persons)
    {
        // Create a EF Context
        using (var ctx = new MyDbEntities())
        {
            // Iterate
            foreach (var person in persons)
            {
                // Get current keywords
                var keywords = new List<Keyword>(person.Keywords).ToList();

                // Fetch Person from DB (if its not a NEW entry). Must use Include, else it's not working.
                var newPerson = ctx.Persons
                                       .Include("Keywords")
                                       .FirstOrDefault(s => s.Id == person.Id) ?? person;

                // Clear keywords of the object, else EF will INSERT them.. Silly.
                newPerson.Keywords.Clear();

                // Insert or update?
                ctx.Entry(newPerson).State = newPerson.Id == 0 ? EntityState.Added : EntityState.Modified;

                // Apply new scalar values
                if(newPerson.Id != 0)
                {
                    person.Id = newPerson.Id;
                    ctx.Entry(newPerson).CurrentValues.SetValues(person);

                }

                // Iterate through all keywords
                foreach (var kw in ctx.Keywords)
                {
                    // If the current kw exists in OUR list, add it
                    // - if not, remove the relation from the DB.
                    if (keywords.Any(k => k.Id == kw.Id))
                    {
                        //ctx.Entry(kw).State = EntityState.Unchanged;
                        ctx.Keywords.Attach(kw);
                        newPerson.Keywords.Add(kw);
                    }
                    else
                        newPerson.Keywords.Remove(kw);
                }
            }

            // Save
            ctx.SaveChanges();

        }
    }

这篇关于更新许多到许多导航属性的实体框架6,改变不被保存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆