如何获取CanAddNew是否适用于RIA Services返回的集合

时间:2010-07-15 17:20:22

标签: silverlight silverlight-4.0 wcf-ria-services

RIA Services返回一个实体列表,不允许我添加新项目。以下是我认为的相关细节:

  • 我从2010年4月中旬开始使用Silverlight 4和RIA Services 1.0的发布版本。
  • 我有一个DomainService,其查询方法返回List<ParentObject>
  • ParentObject包含一个名为“Children”的属性,定义为List<ChildObject>
  • 在DomainService中,我为ParentObject定义了CRUD方法,并为查询,删除,插入和更新功能提供了适当的属性。
  • ParentObject类具有标记有[Key]属性的Id属性。它还有“Children”属性,标有属性[Include],[Composition]和[Association(“Parent_Child”,“Id”, “的ParentId”)]。
  • ChildObject类具有标记有[Key]属性的Id以及包含父标识的外键“ParentId”。

在客户端,数据已成功返回,我将查询结果分配给PagedCollectionView,如下所示:

_pagedCollectionView = new PagedCollectionView(loadOperation.Entities);  

当我尝试将新的ParentObject添加到PagedCollectionView时,如下所示:

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

我收到以下错误:

此视图不允许“添加新内容”。

在进一步调查中,我发现_pagedCollectionView.CanAddNew为“false”且无法更改,因为该属性是只读的。

我需要能够在PagedCollectionView中添加和编辑ParentObjects(当然还有相关的子节点)。我需要做什么?

3 个答案:

答案 0 :(得分: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有约束力,我认为这就是你所期望的。

[编辑] 第二个警告是这种类型是为绑定而设计的。要完全使用可用的List操作(Clear等),您还需要覆盖其他一些写入的方法。

我打算整理一篇文章,对此进行更深入的解释,但就目前而言,我希望这已经足够了。

凯尔

答案 1 :(得分:1)

我和你有同样的问题。理想情况下,我希望能够使用PCV中的AddNew()但是唉,不行......

我目前正在使用的解决方法。如果您使AddNew()工作,请发布答案。

您可以在DomainContext上检索EntitySet&lt; T&gt;而不是使用AddNew。通过说Context.EntityNamePlural(即:Context.Users = EntitySet&lt; User&gt;)

您可以通过调用Add()然后使用Context.SubmitChanges()将新实体添加到该EntitySet,以将其发送到DB。要反映客户端上的更改,您需要重新加载(Context.Load())

我在PCV没有运气之后大约15分钟就完成了这项工作,所以我相信它可以更好地工作,但希望这会让你前进。

答案 2 :(得分: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为“false”,即使底层EntitySet支持此功能。)< / p>

我认为Kyle McClellan的方法(参见他的回答)可能会被某些人所喜欢,因为它将更改封装到EntitySet中,但我发现为了我的目的,在loadOperation.Entities周围添加ObservableCollection包装是不必要的。

非常感谢Dallas Kinzel一路上的提示!