Entity Framework - Добавление объектов (и их свойств навигации) с общими первичными ключами - PullRequest
0 голосов
/ 15 марта 2012

Это упрощенная версия проблемы, которую я пытаюсь решить:

Есть две сущности:

Item

ItemID (PK)

Другие простые свойства ...

WorkItem (свойство навигации)

WorkItem

ItemID (PK)

Другие простые свойства ...

Item (свойство навигации)

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

Это я могу сделать:

  Item newItem = Item.CreateItem(0, blah,blah,blah);
  service.AddToItems(newItem);


  WorkItem newWorkItem = new WorkItem();           
  service.AddToWorkItems(newWorkItem);

  //set the navigation properties
  newItem.WorkItem = newWorkItem;
  newWorkItem.Item = newItem;

К сожалению, когда дело доходит до сохранения, это не удается.Я полагаю, что EF, пытаясь установить связь элементов WorkItem, пытается установить первичный ключ WorkItem.

Может кто-нибудь рассказать мне о правильном способе достижения этого, пожалуйста?

Обновить:Итак, я попытался построить модель с использованием наследования.Модель строит и проверяет.

К сожалению, добавление службы данных WCF для моей модели и попытка просмотра службы в браузере дает мне следующее:

  ..... <m:message xml:lang="en-US">An error occurred while processing this request.    </m:message>
<m:innererror>
  <m:message>Navigation Properties are not supported on derived entity types. Entity Set 'app_Items' has a instance of type 'tempmodel.app_CostItem', which is an derived entity type and has navigation properties. Please remove all the navigation properties from type 'tempmodel.app_CostItem'.</m:message>
  <m:type>System.InvalidOperationException</m:type>
  <m:stacktrace>   at System.Data.Services.Serializers.SyndicationSerializer.WriteObjectProperties(IExpandedResult expanded, ......

CostItem - другая сущность, напримерWorkItem, который является производным от Item.

Ответы [ 2 ]

0 голосов
/ 21 марта 2012

Мне удалось создать фиктивное свойство в каждом из моих частичных "под" -классов на стороне клиента:

    private Item _BaseItem;
    [AtomIgnore]
    internal Item BaseItem
        {
        get
            {
            if (_BaseItem != null)
                return _BaseItem;
            else
                return this.Item;                
            }
        set
            {
            _BaseItem = value;
            OnPropertyChanged("Item");
            }
        }

Код на стороне клиента использует это свойство BaseItem для обратного прохождения графа объекта. Поэтому код для установки отношений теперь выглядит так:

 Item newItem = Item.CreateItem(0, blah,blah,blah);
 service.AddToItems(newItem);


 WorkItem newWorkItem = new WorkItem();           
 service.AddToWorkItems(newWorkItem);

 //set the navigation properties
 newItem.WorkItem = newWorkItem;
 newWorkItem.**BaseItem** = newItem;

Обратите внимание, свойство BaseItem объявлено внутренним; это так, что сериализатор не будет пытаться сериализовать свойство и отправить его на сервер.

[AtomIgnore] - это атрибут, который я создал и ищу в своем обработчике для DataServiceContext.WritingEntity. Обработчик удаляет свойства, помеченные этим атрибутом, до их отправки на сервер. Эта техника, похоже, не работает, если свойство относится к типу ref, поэтому используется внутреннее.

Объявление его внутренним также означает, что оно не может быть связано с XAML, к счастью, мне нужно было привязать только пару свойств, чтобы обойти это было просто.

0 голосов
/ 15 марта 2012

Исходя из приведенного вами примера, я считаю, что вы должны использовать наследование. Сущность WorkItem должна наследоваться от сущности Item. Затем в вашем коде вам нужно будет работать только с сущностью WorkItem, и она будет также иметь все свойства сущности Item. Кроме того, сущность WorkItem будет использовать ключ от сущности Item.

...