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

时间:2011-05-02 18:21:53

标签: c# entity-framework entity-framework-4 linq-to-entities

我有以下代码从第三方下载对象,我想继续插入/更新到我的数据库。模型中有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) 

1 个答案:

答案 0 :(得分:3)

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

不是设置MyObjectsFromSQL.MyTableChildObject = DownloadedObject.MyTableChildObject;,而是需要逐个比较集合,添加MyObjectsFromSQL.MyTableChildObject中尚不存在的项目,删除DownloadedObject.MyTableChildObject中未显示的项目{1}},并更新两者中存在的每个项目的标量值。

同样,如果子对象具有其他子对象,则需要以递归方式遵循相同的模式。