Обновите EntityCollection в EntityType из другого объекта - PullRequest
1 голос
/ 02 мая 2011

У меня есть следующий код, который загружает объект от третьего лица, и я хочу сохранить вставки / обновления в моей базе данных.В модели 10 таблиц, созданных на основе SQL Server, которые были созданы из объекта SOAP.Для простоты я создал следующий пример, чтобы показать только одну дочернюю таблицу (но в действительности есть несколько слоев MyTable -> MyTableChild -> MyTableGrandChild), поэтому мы можем предположить, что у меня есть MyTable EntityType и MyTableChild EntityType, где есть EntityCollectionобъектов MyTableChild, содержащихся в 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();
}

Я пробовал множество вещей, однако для меня имело смысл попытаться скопировать значения из 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 Ответ

3 голосов
/ 02 мая 2011

Entity Framework не может автоматически сравнивать коллекции связанных объектов, поэтому вам нужно сделать эту логику самостоятельно.

Вместо установки MyObjectsFromSQL.MyTableChildObject = DownloadedObject.MyTableChildObject; вам нужно будет сравнивать пошаговые коллекции, добавляя элементы, которых еще нет в MyObjectsFromSQL.MyTableChildObject, удаляя элементы, которые не отображаются в DownloadedObject.MyTableChildObject, и обновление скалярных значений для каждого элемента, который существует в обоих.

Аналогично, если дочерние объекты имеют другие дочерние объекты, вам нужно будет следовать тому же шаблону рекурсивно.

...