复杂实体框架链接图问题:如何限制更改设置/打破图形? [英] Complex Entity Framework linked-graphs issue: how to limit change set / break the graph?

查看:161
本文介绍了复杂实体框架链接图问题:如何限制更改设置/打破图形?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个EDMX包含句子单词,说和一个句子包含三个单词,说。表格之间存在适当的FK关系。

I have an EDMX containing Sentences, and Words, say and a Sentence contains three Words, say. Appropriate FK relationships exist between the tables.

我创建了一些单词: Word word1 = new Word(); Word word2 = ...

我构建句子: Sentence x = new Sentence(word1,word2,word3 );

我建立另一个句子: Sentence y = new Sentence(word1,word4,word5);

我尝试将 x 保存到数据库,但EF构建一个包含一切,包括 y word4 word5 t准备保存到数据库。当SaveChanges()发生时会抛出异常:无法确定...关系的主体结束。多个添加的实体可能具有相同的主键。

I try to save x to the database, but EF builds a change set that includes everything, including y, word4 and word5 that aren't ready to save to the database. When SaveChanges() happens it throws an exception: Unable to determine the principal end of the ... relationship. Multiple added entities may have the same primary key.

我认为这样做是因为 Word 一个 EntityCollection< Sentence> 从两个表之间的FK关系,因此句子 y 是不可分割的链接到句子 x 通过 word1

I think it does this because Word has an EntityCollection<Sentence> on it from the FK relationship between the two tables, and thus Sentence y is inextricably linked to Sentence x through word1.

所以我删除导航属性句子 Word ,然后重试。它仍然尝试将整个图形放入更改集中。

So I remove the Navigation Property Sentences from Word and try again. It still tries to put the entire graph into the change set.

实体框架专家对于打破此连接的方法有什么建议。基本上我想要的是从 Sentence Word 的单向映射;我不想在Word上使用 EntityCollection< Sentence> ,我不希望对象图形与此相互交织。

What suggestions do the Entity Framework experts have for ways to break this connection. Essentially what I want is a one-way mapping from Sentence to Word; I don't want an EntityCollection<Sentence> on Word and I don't want the object graph to get intertwined like this.

代码示例:
这会将两个句子放入数据库,因为Verb1链接它们,EF会在添加/保存更改时探索现有对象和添加对象的整个图形。 / p>

Code sample: This puts two sentences into the database because Verb1 links them and EF explores the entire graph of existing objects and added objects when you do Add/SaveChanges.

    Word subject1 = new Word(){ Text = "Subject1"};
    Word subject2 = new Word(){ Text = "Subject2"};
    Word verb1 = new Word(){ Text = "Verb11"};
    Word object1 = new Word(){ Text = "Object1"};
    Word object2 = new Word(){ Text = "Object2"};


    Sentence s1 = new Sentence(){Subject = subject1, Verb=verb1, Object=object1};
    Sentence s2 = new Sentence(){Subject=subject2, Verb=verb1, Object=object2};

    context.AddToSentences(s1);
    context.SaveChanges();

    foreach (var s in context.Sentences)
    {
        Console.WriteLine(s.Subject + " " + s.Verb + " " + s.Object);
    }


推荐答案

工作是重命名和隐藏数据库生成的属性(例如SubjectP),维护设置的Word的单独的私有副本,然后在保存期间修复它:

One alternative that does seem to work is to rename and hide the database generated properties (e.g. SubjectP), maintain a separate private copy of the Word that is set, and then fix it up during save:

在句子中:

    private Word subject;
    ...

    public Word Subject { get {return this.subject ?? this.SubjectP;} set {this.subject = value; }}

    public void FixSelfUp()
    {
        if (this.subject != null && subject != this.SubjectP) this.SubjectP = this.subject;
    ...

在SaveChanges()...

And in SaveChanges() ...

    var items = this.context.ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Added | System.Data.EntityState.Modified);
    // now iterate over them, find any Sentences and call to fix them up.

这使得Sentence的行为就像它的行为,允许设置和获取每个Word它不允许EF将它们一起加入到一个大图中。

This makes the Sentence behave just like it was intended to behave, allows setting and getting of each Word on it and doesn't allow EF to join them all together into one big graph.

但是肯定有比这更好的方法!

But surely there's a better way than this!

这篇关于复杂实体框架链接图问题:如何限制更改设置/打破图形?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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