【问题标题】:copy records from between two databases using EF使用 EF 在两个数据库之间复制记录
【发布时间】:2011-08-03 10:25:36
【问题描述】:

我需要使用 EF 将数据从一个数据库复制到另一个数据库。例如。我有以下表格关系:Forms->FormVersions->FormLayouts...我们在两个数据库中都有不同的表格,我们希望将它们收集到一个数据库中。基本上我想从一个 DB 递归加载 Form 对象并将其保存到另一个 DB 和他的所有引用。如果第二个数据库中存在具有相同 ID 的对象,我还需要更改对象和相关对象的 ID。

到目前为止,我有以下代码:

Form form = null;
using (var context = new FormEntities())
        {
            form = (from f in context.Forms
                        join fv in context.FormVersions on f.ID equals fv.FormID
                        where f.ID == 56
                        select f).First();
        }

        var context1 = new FormEntities("name=FormEntities1");
        context1.AddObject("Forms", form);
        context1.SaveChanges();

我收到错误消息:“EntityKey 属性只能在属性的当前值为 null 时设置。”

您能帮忙实施吗?

【问题讨论】:

    标签: entity-framework


    【解决方案1】:

    最简单的解决方案是创建表单(新对象)的副本并添加该新对象。否则你可以试试:

    1. 致电context.Detach(form)
    2. 将表单的EntityKey 设置为空
    3. 致电context1.AddObject(form)

    【讨论】:

    • 我已经尝试过您的解决方案。它工作正常,但仅适用于 Form 对象。当我分离表单时,我会丢失所有相关的对象。因此,如果 Form 有 10 个 FormVersions 并且我进行了分离,则 form 有 0 个 FormVersions。我想实现复制所有层次结构,而不仅仅是根对象。
    • 是的,这正是发生的事情,除了创建表单及其所有关系的完整副本之外,没有解决方案(最简单的解决方案是序列化和反序列化表单以获得完整的克隆 - 但表单必须可序列化)。
    • 谢谢。序列化对我来说是一个解决方案。但是在生成 EF 模型的默认模板中,实体集合有 [XmlIgnoreAttribute()] 属性。这意味着相关对象没有被序列化。是否有任何选项如何在不修改模板的情况下序列化相关对象?
    【解决方案2】:

    我会优先考虑 E.J. 的回答。假设您将使用实体框架,您将面临的主要问题之一是关系管理。您的代码应使用 Include 方法来确保相关对象包含在选择操作的结果中。您拥有的联接不会有此效果。

    http://msdn.microsoft.com/en-us/library/bb738708.aspx

    此外,分离对象不会自动分离相关对象。您可以以相同的方式分离它们,但是这里的问题是,当每个对象被分离时,它与上下文中其他对象的关系就会被破坏。

    手动恢复关系可能是您的一种选择,但可能值得查看 EntityGraph。该框架允许您定义对象图,然后对其执行分离等操作。整个图在单个操作中分离,其关系完好无损。

    我使用此框架的经验与 RIA 服务和 Silverlight 相关,但我相信 .Net 也支持这些操作。

    http://riaservicescontrib.codeplex.com/wikipage?title=EntityGraphs

    Edit1:我刚刚检查了 EntityGraph 文档,发现 DetachEntityGraph 位于 RIA 特定层中,不幸的是,它排除了您的选项。

    Edit2:Alex Jame 对以下问题的回答是您问题的解决方案。不要一开始就将对象加载到上下文中 - 使用 nottracking 选项。这样你就不需要分离它们,这就是导致问题的原因。

    Entity Framework - Detach and keep related object graph

    【讨论】:

    • 感谢您的文章。我现在已经通过使用 Ladislav 的解决方案解决了我的问题。
    【解决方案3】:

    如果您只做几条记录,Ladislav 的建议可能会奏效,但如果您要移动大量数据,您应该/可以考虑在存储过程中进行此移动。整个操作可以在服务器上完成,无需将对象从 db 服务器移动到前端然后再返回。一个 SP 调用就可以完成所有工作。

    性能会好很多,这在您的情况下可能无关紧要。

    【讨论】:

    • 感谢您的回复。在这种情况下,性能对我来说并不重要。更重要的是我要复制的相关表的大层次结构。例如,我在帖子中只写了三个表,但几乎有 20 个表:Forms->FormVersions->FormLayouts->LayoutRows->LayoutColumns->....n。我可以在存储过程中做到这一点,但我需要手动遍历所有相关表。我正在发现 EF 是否可以为我做这件事。
    猜你喜欢
    • 2010-09-14
    • 2013-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-08
    • 1970-01-01
    相关资源
    最近更新 更多