如何在域上下文中添加新实体,并在SubmitChanges之前立即在数据绑定控件中看到它?

时间:2011-03-11 06:39:08

标签: silverlight-4.0 entity-framework-4 wcf-ria-services

我使用Entity Frameworks 4 CTP5获得了Silverlight 4 RIA Services(SP1)应用程序。我可以将网格或列表框数据绑定到域上下文加载的IEnumerable,它显示来自服务器的数据。大。

现在我想创建一个新的MyEntity实例并将其添加到客户端数据中,以便用户可以看到新添加的实体。 MyEntity是一个真正的实体后代,而不是POCO。

我能找到的唯一添加方法是domainContext.EntityContainer.GetEntitySet<MyEntity>().Add(newobj)

这会将新实体添加到域上下文中,并且domainContext.HasChanges确实变为true,但新实体不会显示在数据绑定控件中。

如何在SubmitChanges之前让新实体显示在数据绑定控件中?

(可能与多年前从未得到答案的this SO问题有关)

以下是每个请求的域服务的服务器端声明:

[EnableClientAccess()]
public class MyDomainService : LinqToEntitiesDomainService<MyObjectContext>
{
    protected override MyObjectContext CreateObjectContext()
    {
        return new MyObjectContext();
    }

    public IQueryable<MyEntity> GetMyEntities()
    {
        return this.ObjectContext.MyEntities;
    }

    public void InsertMyEntity(MyEntity MyEntity)
    {
        // ...
    }

    public void UpdateMyEntity(MyEntity currentMyEntity)
    {
        // ...
    }

    public void DeleteMyEntity(MyEntity MyEntity)
    {
        // ...
    }
}

3 个答案:

答案 0 :(得分:2)

我已经结合了我自己的试验和错误以及其他一些对此问题的回答提供的提示。

我缺少的关键点是,ViewModel跟踪DomainContext并将查询结果分发给View for databinding是不够的。如果希望ViewModel执行的实体添加和删除在DomainContext.SubmitChanges()之前出现在UI中,ViewModel还必须捕获并保留查询结果。 ViewModel必须将这些添加应用于查询结果的集合视图。

View数据绑定的ViewModel集合属性。在这种情况下,我使用Telerik QueryableDomainServiceCollectionView ,但可以使用其他集合视图:

    public IEnumerable<MyEntity> MyEntities
    {
        get
        {
            if (this.view == null)
            {
                DomainContextNeeded();
            }
            return this.view;
        }
    }

    private void DomainContextNeeded()
    {
        this.context = new MyDomainContext();
        var q = context.GetMyEntitiesQuery();
        this.view = new Telerik.Windows.Data.QueryableDomainServiceCollectionView<MyEntity>(context, q);
        this.view.Load();
    }

ViewModel函数,为要显示的UI添加新实体:

public void AddNewMyEntity(object selectedNode)
{
    var ent = new MyEntity() { DisplayName = "New Entity" };

    if (selectedNode == null)
    {
        this.view.AddNew(ent);
    }
    else if (selectedNode is MyEntity)
    {
        ((MyEntity)selectedNode).Children.Add(ent);
    }
}

其他回复提到了ObservableCollection。查询结果和集合视图可能不返回ObservableCollection的实例。它们可能只是IEnumerables。重要的是他们实现了INotifyCollectionChanged和 IEditableCollectionView

感谢那些做出回应的人。我对每个有用的回复都给了+1,但由于没有一个直接解决了我的问题,我无法将任何标记作为最终答案。

答案 1 :(得分:1)

您的domainContext将具有属性domainContext.MyEntities。当你添加它时它不会出现在那里吗?

绑定到该集合或观看该集合的更改。

domainContext.MyEntities.PropertyChanged + = MyEventHandler;

答案 2 :(得分:1)

我假设您将控件绑定到IEnumerable提供的LoadOperation<TEntity>.Entities。在这种情况下,您的绑定源不是DomainContext.GetEntitySet<MyEntity>()

DomainContext.GetEntitySet<MyEntity>()包含您MyEntity当前跟踪的所有实例,包括您使用.Add()添加的实例。

LoadOperation<TEntity>.Entities仅包含上次LoadOperation / Query实际加载的MyEntity实例。

您有两个选择:将新实体添加到控件的ItemsSource集合中(我建议)或使用DomainContext.GetEntitySet<MyEntity>()的内容重建集合。但是,这可能包含之前尚未清除的其他元素。