从另一个对象更新 EntityType 内的 EntityCollection

发布于 2024-11-04 06:45:32 字数 1915 浏览 1 评论 0原文

我有以下代码从第三方下载对象,我想将插入/更新保留到我的数据库中。模型中有 10 个从 SQL Server 创建的表,这些表是从 SOAP 对象生成的。为简单起见,我创建了以下示例以仅显示单个子表(但实际上有多个层 MyTable -> MyTableChild -> MyTableGrandChild),因此我们可以假设我有一个 MyTable EntityType 和一个 MyTableChild EntityType,其中有MyTable 中包含的 MyTableChild 对象的 EntityCollection。

using (Model.MyEntities context = new Model.MyEntities())
{
    var MyObjectsFromSQL = from a in context.MyTable select a;

    [AutoMapper][1].CreateMap<SOAPChildObject, Model.MyTableChild>();
    [AutoMapper][2].Mapper.CreateMap<SOAPObject, Model.MyTable>();
    var DownloadedObjects = Mapper.Map<SOAPObject[], IEnumerable<Model.MyTable>>(ArrayOfSOAPObjects);

    foreach (var DownloadedObject in DownloadedObjects)
    {
        Model.MyTable CurrentObject = context.MyTable.Where(a => a.key == D2.key).Single();
        // How do I check the changes in the DownloadedObject against
        //   the MyObjectsFromSQL so I can send the changes back to SQL
    }
    context.SaveChanges();
}

我尝试了多种方法,但对我来说有意义的是尝试将 DownloadedObject 中的值复制到 CurrentObject 中,并让框架发挥其魔力。这似乎适用于非 EntityCollection 成员,但给我带来了 EntityCollections 的错误。

MyObjectsFromSQL.MyStringObject = DownloadedObject.MyStringObject
MyObjectsFromSQL.MyTableChildObject = DownloadedObject.MyTableChildObject;  // ERROR: System.InvalidOperationException!

System.InvalidOperationException was unhandled
Message=The EntityCollection has already been initialized. The InitializeRelatedCollection method should only be called to initialize a new EntityCollection during deserialization of an object graph.
Source=System.Data.Entity
StackTrace:
    at System.Data.Objects.DataClasses.RelationshipManager.InitializeRelatedCollection[TTargetEntity](String relationshipName, String targetRoleName, EntityCollection`1 entityCollection)
    at Model.MyTable.set_MyTableChild(EntityCollection`1 value) 

I have the following code that downloads an object from a 3rd party and I want to persist the inserts/updates to my database. There are 10 tables in the model that were created from SQL Server that were generated from the SOAP object. For simplicity I created the following example to only show a single child table (but in reality there are several layers MyTable -> MyTableChild -> MyTableGrandChild), so we can assume that I have a MyTable EntityType and a MyTableChild EntityType where there is an EntityCollection of MyTableChild objects contained in MyTable.

using (Model.MyEntities context = new Model.MyEntities())
{
    var MyObjectsFromSQL = from a in context.MyTable select a;

    [AutoMapper][1].CreateMap<SOAPChildObject, Model.MyTableChild>();
    [AutoMapper][2].Mapper.CreateMap<SOAPObject, Model.MyTable>();
    var DownloadedObjects = Mapper.Map<SOAPObject[], IEnumerable<Model.MyTable>>(ArrayOfSOAPObjects);

    foreach (var DownloadedObject in DownloadedObjects)
    {
        Model.MyTable CurrentObject = context.MyTable.Where(a => a.key == D2.key).Single();
        // How do I check the changes in the DownloadedObject against
        //   the MyObjectsFromSQL so I can send the changes back to SQL
    }
    context.SaveChanges();
}

I have tried a variety of things, however what made sense to me was to try to copy the values from the DownloadedObject into the CurrentObject and let the framework do its magic. That seemed to work for the non-EntityCollection members, but gave me errors for the EntityCollections.

MyObjectsFromSQL.MyStringObject = DownloadedObject.MyStringObject
MyObjectsFromSQL.MyTableChildObject = DownloadedObject.MyTableChildObject;  // ERROR: System.InvalidOperationException!

System.InvalidOperationException was unhandled
Message=The EntityCollection has already been initialized. The InitializeRelatedCollection method should only be called to initialize a new EntityCollection during deserialization of an object graph.
Source=System.Data.Entity
StackTrace:
    at System.Data.Objects.DataClasses.RelationshipManager.InitializeRelatedCollection[TTargetEntity](String relationshipName, String targetRoleName, EntityCollection`1 entityCollection)
    at Model.MyTable.set_MyTableChild(EntityCollection`1 value) 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

睡美人的小仙女 2024-11-11 06:45:32

实体框架无法自动比较相关对象的集合,因此您需要自己执行此逻辑。

您需要逐个比较集合,添加 MyObjectsFromSQL.MyTableChildObject 中不存在的项目,而不是设置 MyObjectsFromSQL.MyTableChildObject = DownloadedObject.MyTableChildObject; > 然而,删除未出现在 DownloadedObject.MyTableChildObject 中的项目,并更新两者中存在的每个项目的标量值。

同样,如果子对象有其他子对象,您将需要递归地遵循相同的模式。

Entity Framework can't automatically compare collections of related objects, so you'll need to do this logic yourself.

Rather than setting MyObjectsFromSQL.MyTableChildObject = DownloadedObject.MyTableChildObject;, you'll need to compare the collections piece-by-piece, adding items that don't exist in MyObjectsFromSQL.MyTableChildObject yet, removing items that don't appear in DownloadedObject.MyTableChildObject, and updating the scalar values on each item that exists in both.

Likewise, if the child objects have other child objects, you'll need to follow the same pattern, recursively.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文