我有以下代码从第三方下载对象,我想继续插入/更新到我的数据库。模型中有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)
答案 0 :(得分:3)
实体框架无法自动比较相关对象的集合,因此您需要自己执行此逻辑。
不是设置MyObjectsFromSQL.MyTableChildObject = DownloadedObject.MyTableChildObject;
,而是需要逐个比较集合,添加MyObjectsFromSQL.MyTableChildObject
中尚不存在的项目,删除DownloadedObject.MyTableChildObject
中未显示的项目{1}},并更新两者中存在的每个项目的标量值。
同样,如果子对象具有其他子对象,则需要以递归方式遵循相同的模式。