Как получить CanAddNew может быть правдой для коллекции, возвращенной RIA Services - PullRequest
1 голос
/ 15 июля 2010

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

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

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

_pagedCollectionView = new PagedCollectionView(loadOperation.Entities);  

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

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

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

"« Добавить новый »не разрешено для этого представления."

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

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

Ответы [ 3 ]

4 голосов
/ 16 июля 2010

Вчера я просто играл с решением и чувствовал себя довольно хорошо о том, как оно работает.Причина, по которой вы не можете добавить это исходная коллекция (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, я предполагаю, что это то, что вы ожидаете.

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

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

Кайл

1 голос
/ 15 июля 2010

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

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

Вместо использования AddNew в вашем DomainContext вы можете получить EntitySet , сказав Context.EntityNamePlural (то есть: Context.Users = EntitySet )

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

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

0 голосов
/ 20 июля 2010

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

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

_pagedCollectionView = new PagedCollectionView(context.ParentObjects);

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

context.ParentObjects.Add();

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

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

Большое спасибо Далласу Кинзелю за его советы по пути!

...