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

发布于 2024-10-21 13:14:11 字数 1254 浏览 1 评论 0原文

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

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

我能找到的唯一 Add 方法是 domainContext.EntityContainer.GetEntitySet().Add(newobj)

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

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

(可能与这个几年前的问题从未得到答案)

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

[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)
    {
        // ...
    }
}

I've got a Silverlight 4 RIA Services (SP1) app using Entity Frameworks 4 CTP5. I can databind a grid or listbox to the IEnumerable loaded by the domain context and it shows data from the server. Great.

Now I want to create a new instance of MyEntity and add it to the client-side data so that the user can see the newly added entity. MyEntity is a true entity descendant, not a POCO.

The only Add method I can find is domainContext.EntityContainer.GetEntitySet<MyEntity>().Add(newobj)

This does add the new entity to the domain context, and the domainContext.HasChanges does become true, but the new entity doesn't show up in the databound controls.

How do I get the new entity to show up in the databound controls prior to SubmitChanges?

(Probably related to this SO question from years ago that never got an answer)

Here's the server side declarations of the domain service, per requests:

[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)
    {
        // ...
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

另类 2024-10-28 13:14:12

我结合自己的尝试和错误以及对此问题的其他一些回答提供的提示,解决了这个问题。

我忽略的关键点是 ViewModel 跟踪 DomainContext 并将查询结果分发给 View 进行数据绑定是不够的。如果您希望 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();
    }

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

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 的实例。它们可能只是 IEnumerable。关键是它们实现了 INotifyCollectionChanged 和 IEditableCollectionView

感谢那些贡献回复的人。我已经对每个有帮助的回复进行了+1,但由于没有一个直接解决了我的问题,所以我无法证明将任何回复标记为最终答案是合理的。

I've figured this out with a combination of my own trial and error and hints provided by some of the other responses to this question.

The key point I was missing was that it's not enough for the ViewModel to keep track of the DomainContext and hand out query results to the View for databinding. The ViewModel also has to capture and retain the query results if you want entity adds and deletes performed by the ViewModel to appear in the UI before DomainContext.SubmitChanges(). The ViewModel has to apply those adds to the collection view of the query results.

The ViewModel collection property for View databinding. In this case I'm using the Telerik QueryableDomainServiceCollectionView, but other collection views can be used:

    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();
    }

The ViewModel function that adds a new entity for the UI to display:

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);
    }
}

Other responses mentioned ObservableCollection. The query results and the collection view may not return instances of ObservableCollection. They could be just IEnumerables. What is critical is that they implement INotifyCollectionChanged and IEditableCollectionView.

Thanks to those who contributed responses. I've +1'd each response that was helpful, but since none directly solved my problem I couldn't justify marking any as the definitive answer.

冷默言语 2024-10-28 13:14:12

您的domainContext 将具有一个属性domainContext.MyEntities。添加的时候没有显示出来吗?

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

domainContext.MyEntities.PropertyChanged += MyEventHandler;

Your domainContext will have a property domainContext.MyEntities. Does it not show up in there when you add it?

Bind to that collection or watch that collection for changes.

domainContext.MyEntities.PropertyChanged += MyEventHandler;

倚栏听风 2024-10-28 13:14:12

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

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

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

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

I assume you bind your control to the IEnumerable which is provided by LoadOperation<TEntity>.Entities. In that case your binding source is not the DomainContext.GetEntitySet<MyEntity>().

DomainContext.GetEntitySet<MyEntity>() holds all your currently tracked instances of MyEntity, including the one you add with .Add().

LoadOperation<TEntity>.Entities only contains the instances of MyEntity that were actually loaded by your last LoadOperation/Query.

You have two options: Either add the new entity to the ItemsSource-collection for your control (I recommend that) or rebuild the collection with the contents of DomainContext.GetEntitySet<MyEntity>(). That may contain other elements that you have not cleared out before, though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文