2010-07-15 4 views
1

RIA Services возвращает список объектов, которые не позволят мне добавлять новые элементы. Вот то, что я считаю, что соответствующие детали:Как получить CanAddNew, чтобы быть правдой для коллекции, возвращенной службами RIA

  • Я использую выпущенные версии Silverlight 4 и RIA Services 1.0 с середины апреля 2010 года
  • У меня есть DomainService с методом запроса, возвращается List<ParentObject>.
  • ParentObject включает свойство «Дети», которое определено как List<ChildObject>.
  • В DomainService Я определил методы CRUD для ParentObject с соответствующими атрибутами для функций Query, Delete, Insert и Update.
  • Класс ParentObject имеет свойство Id, помеченное атрибутом [Key]. Он также имеет свойство «Дети», отмеченное атрибутами [Include], [Composition] и [Association («Parent_Child», «Id», «ParentId»)].
  • Класс ChildObject имеет идентификатор, помеченный атрибутом [Key], а также внешний ключ «ParentId», который содержит идентификатор родителя.

На стороне клиента, данные успешно вернулся и я назначу результаты запроса к PagedCollectionView, как это:

_pagedCollectionView = new PagedCollectionView(loadOperation.Entities); 

Когда я пытаюсь добавить новый ParentObject к PagedCollectionView, как это:

ParentObject newParentObject = (ParentObject)_pagedCollectionView.AddNew(); 

Я получаю следующее сообщение об ошибке:

«„Добавить новый“не допускается для этой точки зрения»

В ходе дальнейшего расследования я обнаружил, что _pagedCollectionView.CanAddNew является «ложным» и не может быть изменен, поскольку свойство доступно только для чтения.

Мне нужно иметь возможность добавлять и редактировать ParentObjects (со связанными детьми, конечно) с PagedCollectionView. Что мне нужно сделать?

ответ

0

Для моей конкретной ситуации, я считаю, что лучше всего подходит это (ваш пробег может изменяться):

Используйте PagedCollectionView (PCV) в качестве обертки вокруг context.EntityNamePlural (в моем случае , context.ParentObjects), который является EntitySet. (Использование loadOperation.Entities не работает для меня, потому что она всегда только для чтения.)

_pagedCollectionView = new PagedCollectionView(context.ParentObjects); 

Затем связываются с PCV, но выполнить добавление/удаление непосредственно против context.EntityNamePlural EntitySet. PCV автоматически синхронизируется с изменениями, внесенными в базовый EntitySet, поэтому этот подход означает, что мне не нужно беспокоиться о проблемах с синхронизацией.

context.ParentObjects.Add(); 

(Причина выполнения добавления/удаления непосредственно против EntitySet вместо использования PCV является то, что реализация PCV по IEditableCollectionView несовместима с EntitySet вызывает IEditableCollectionView.CanAddNew «ложным», даже несмотря на то, лежащий в основе EntitySet поддерживает эту функция.)

Я думаю, что подход Кайла Макклеллана (см. его ответ) может быть предпочтительным для некоторых, потому что он инкапсулирует изменения в EntitySet, но я обнаружил, что для моих целей было необязательно добавлять обсервер ObservableCollection вокруг loadOperation.Entities ,

Огромное спасибо Далласу Кинцелю за его советы по пути!

1

У меня такая же проблема, как и вы. В идеале я бы хотел использовать AddNew() из PCV, но, увы, нет ...

У меня есть обходной путь, который я использую в настоящее время. Если вы создаете работу AddNew(), отправьте ответ.

Вместо использования AddNew на вашем DomainContext вы можете извлечь EntitySet <T> говоря Context.EntityNamePlural (то есть: Context.Users = EntitySet < Пользователь >)

Вы можете добавить новый объект к тому, что EntitySet, вызывая Add(), а затем Context.SubmitChanges(), чтобы отправить его в БД. Чтобы отразить изменения на клиенте, вам нужно будет перезагрузить (Context.Load())

Я только что сделал эту работу около 15 минут назад после того, как вам не повезло с PCV, поэтому я уверен, что ее можно заставить работать лучше, но, надеюсь, это заставит вас двигаться вперед.

+0

Спасибо за обходной путь, Даллас. На данный момент я все еще надеюсь найти способ заставить его работать «правильно», но если все остальное не удастся, хорошо иметь план резервного копирования. (Если я вырезал RIA Services из состава и просто высмеял данные на стороне клиента, бросьте его в ObservableCollection и оберните, что с PCV, я могу добавлять элементы без проблем.) Должен быть способ получить PCV, чтобы добавить новые элементы. – MylesRip

+0

Я смотрю на это немного больше, и я считаю, что причина заключается не в том, что PCV не разрешает новые элементы, а в том, что сборка, возвращаемая из операции Context Load(), является ReadOnly. Звучит так, что это проблема для многих людей. Некоторые из них предложили и попытались опубликовать «EntityCollectionView», который будет поддерживать операции, которые мы пытаемся использовать, но это не похоже на то, что этот класс существует где угодно в окончательной форме. из персонажей помещает ссылки на другое сообщение –

+0

Следующая ссылка содержит некоторую полезную информацию (прочитайте две страницы в этом блоге после ссылки на дополнительную страницу): http: //www.riaservicesblog.com/Блог/сообщение/View-Model-Collection-Properties-for-WCF-RIA-Services.aspx http://forums.silverlight.net/forums/p/168676/380096.aspx Цитирование из приведенного выше link: «Самый безопасный способ сделать добавление или удаление - сделать их непосредственно в EntitySet». –

4

Я вчера только что поиграл с решением и очень хорошо понял, как это работает. Причина, по которой вы не можете добавить, - это исходная коллекция (op.Entities) доступна только для чтения.Однако, даже если вы можете добавить в коллекцию, вы все равно хотите добавить в EntitySet. Я создал промежуточную коллекцию, которая заботится обо всех этих вещах для меня.

public class EntityList<T> : ObservableCollection<T> where T : Entity 
{ 
    private EntitySet<T> _entitySet; 

    public EntityList(IEnumerable<T> source, EntitySet<T> entitySet) 
     : base(source) 
    { 
     if (entitySet == null) 
     { 
      throw new ArgumentNullException("entitySet"); 
     } 
     this._entitySet = entitySet; 
    } 

    protected override void InsertItem(int index, T item) 
    { 
     base.InsertItem(index, item); 
     if (!this._entitySet.Contains(item)) 
     { 
      this._entitySet.Add(item); 
     } 
    } 

    protected override void RemoveItem(int index) 
    { 
     T item = this[index]; 
     base.RemoveItem(index); 
     if (this._entitySet.Contains(item)) 
     { 
      this._entitySet.Remove(item); 
     } 
    } 
} 

Тогда, я использую его в коде, как это.

dataGrid.ItemsSource = new EntityList<Entity1>(op.Entities, context.Entity1s); 

Единственное предостережение в этой коллекции не активно обновляет EntitySet. Однако, если вы были привязаны к op.Entities, я предполагаю, что это то, что вы ожидаете.

[Редактировать] Второе предупреждение - этот тип предназначен для привязки. Для полного использования доступной операции «Список» («Очистить» и т. Д.) Вам необходимо переопределить некоторые другие методы для записи, хотя также.

Я планирую собрать сообщение, которое объясняет это немного более подробно, но пока я надеюсь, что этого достаточно.

Kyle

+0

Привет, Кайл, я думаю, что этот подход был бы хорош для многих ситуаций. Я помню, где-то читал, что, когда вы используете ObservableCollection, вы теряете отслеживание изменений для добавления/удаления. В моем случае я хочу, чтобы возможности, которые были включены в PagedCollectionView (группировка, сортировка, фильтрация, подкачка), поэтому я думаю, что мне лучше обойти EntitySet «context.Entity1s» в PCV следующим образом: _pagedCollectionView = новый PagedCollectionView (_context.Entity1s); Затем выполните добавление/удаление непосредственно в EntitySet. Кроме того, PCV автоматически обновляется, когда EntitySet изменяется, поэтому мне не нужно синхронизировать. – MylesRip

+0

Фокус с этой опцией заключается в том, что вы не теряете отслеживание изменений для добавления/удаления, потому что список записывается. Кроме того, если вы хотите функциональность PCV, вы передаете список на PCV, как это. _pcv = новый PCV (новый EntityList (...)) Я никогда не буду спорить с кем-то, кто рекомендует связывание с EntitySet, но этот вариант предлагает преимущества IEditableCollectionView (Добавить/Удалить) поддержку. Самая большая разница, с которой вы сталкиваетесь, заключается в том, хотите ли вы обновлять автоматику добавленных и удаленных объектов (обновления обновляются в обоих случаях). Если обновление важно, определенно используйте EntitySet. –

+0

PCV реализует IEditableCollectionView, но по какой-то причине он сообщает, что CanAddNew является «ложным», даже если базовый EntitySet имеет CanAdd равным «true», поэтому я закончил добавление/удаление непосредственно в EntitySet вместо использования метода IEditableCollectionView.AddNew() даже хотя я привязываюсь к PCV. Ваш подход делает то же самое для добавления/удаления и инкапсулирует его красиво, что отлично. Однако вместо того, чтобы передавать в op.Entities и обертывать его в ObservableCollection, почему бы вам просто не пройти (используя ваш пример выше) _context.Entity1s и перенести его в PCV напрямую? – MylesRip

 Смежные вопросы

  • Нет связанных вопросов^_^