Linq to Sql: отсоединение / повторное присоединение объектов для отправки по проводам - PullRequest
2 голосов
/ 28 апреля 2011

Я использую L2S в среде N-уровня, и у меня возникла проблема при попытке отправить связанные объекты по сети. Я заранее прошу прощения за длинный вопрос, но это очень специфическая ситуация.

Обычно я загружаю таблицу, называю ее Items, а другую таблицу называю ItemMappings. Items и ItemsMappings связаны в отношениях один ко многим. Таким образом, у каждого ItemMapping есть свойство ItemId. В L2S я получаю коллекцию ItemMappings в классе Item и ссылку на Item в классе ItemMappings, что замечательно.

Однако из-за среды N-уровня я разработал несколько классов-оболочек, которые инкапсулируют отслеживание изменений на стороне клиента, чтобы его можно было извлечь при возврате на сервер для сохранения. Это работает путем отслеживания изменений для каждого типа объекта. Это означает, что у меня есть один набор отслеживания для элементов (TrackingSet

Таким образом, это означает, что по проводам я отправляю Предметы и ItemMappings отдельно (на самом деле они отправляются вместе в контейнере, но что касается сериализации, то они раздельные). Теперь, если я не вмешиваюсь в процесс сериализации, то, что на самом деле идет по проводам для коллекции элементов, это что-то вроде следующего псевдо-XML:

<items>
  <item>
    <itemId>1</itemId>
    <itemMappings> 
      <itemMapping>
        <itemId>1</itemId>
      </itemMapping>
    </itemMappings>
  </item>
  <item>
    <itemId>2</itemId>
    <itemMappings> 
      <itemMapping>
        <itemId>2</itemId>
      </itemMapping>
    </itemMappings>
  </item>
</items>

Я пытаюсь показать, что коллекция сериализованных элементов включает в себя сопоставления элементов, связанные с элементами. Но поскольку сопоставления элементов на самом деле также отправляются, на самом деле я заканчиваю тем, что отправляю коллекцию сопоставлений элементов дважды: один раз сам по себе и один раз встраиваемый в коллекцию элементов. Это означает, что мой провод неоправданно велик.

Я хочу отделить сущности в методе OnSerializing в моем классе контейнера, оставив только идентификаторы элементов в объектах itemMapping, а затем в методе OnDeserialized повторно связать их на основе этих идентификаторов.

К сожалению, в методе OnSerializing, если я устанавливаю для свойства ItemMapping.Item значение null, а затем пытаюсь установить для свойства ItemID идентификатор элемента, для которого я просто установил значение null, я получаю печально известное исключение ForeignKeyReferenceAlreadyHasValueException. Это просто немного бесит :)

Если вы зашли так далеко с моим вопросом, я уже должен вам спасибо. Если вы понимаете мою проблему и у вас есть какие-либо предложения, я буду благодарен.

1 Ответ

0 голосов
/ 09 января 2012

Изменение свойств экземпляра во время сериализации, безусловно, является причиной неприятностей!

Я рекомендую иметь некоторые классы для запросов к базе данных и другие классы для проводных представлений. Это отделяет вашу базу данных от вашего контракта на обслуживание.

public class ServiceResponse
{
  public List<Item> TheItems {get;set;}
  public List<ItemMapping> TheMappings {get;set;}
}

public class Item
{
  public int ItemId {get;set;}
  // TODO more properties, but no ItemMappings property
}

public class ItemMapping
{
  public int ItemId {get;set;}
  // TODO more properties
}
...