2

似乎所有现有的breathjs示例都在将实体模型传入和传出BreezeController.

但几乎我们所有构建的页面都使用某种形式的视图模型。在我们没有 BreezeJs 的日子里,我们从存储库中检索数据(域模型)以填充(使用 AutoMapper 或手动)视图模型,该模型仅包含该视图所需的数据。WebAPI 仅将视图模型数据发送到浏览器,我们可以在其中填充客户端视图模型(通常是knockoutobservable)。

保存数据时,我们从 a 收集数据<form>以填充输入视图模型,仅将这些数据发送到服务器,其中输入视图模型中的数据被映射到域模型。通过调用存储库SaveChanges()中的DbContext实体来保存更新。

现在,BreezeJs是通过创建一个EFContextProvider. 我见过的例子通常是检索领域模型数据,然后将其全部传递给客户端。

[HttpGet]
    public IQueryable<Item> Items() {
        return _contextProvider.Context.Items;
    }

构建视图模型是客户端 javascript 的工作。

当然我们可以在服务器端构建视图模型:

[HttpGet]
public List<ItemViewModel> Items() {
    var items = _contextProvider.Context.Items
                  .Include("RelatedEntity")
                  .ToList();
    var model = new List<ItemViewModel>();
    .... some code to build model from items ....
    return model;
}

好处是通过网络传输的数据更少,我们可以在服务器端进行许多操作。但我不知道这样修改是否是一个好习惯BreezeController。但至少,它返回列出所有项目所需的数据。

当我尝试 POST 数据时,真正的麻烦来了。

在我发现的 BreezeJs 示例中,他们使用 ako.observableArray()来存储所有域模型数据,比如说vm.items. 然后将新记录newItem构建manager.createEntity到域模型中。在验证数据之后item.entityAspect.validateEntity()newItem被推入vm.items并被manager.saveChanges()调用,它以某种方式SaveChanges()在 BreezeController 上调用。

    [HttpPost]
    public SaveResult SaveChanges(JObject saveBundle) {
        return _contextProvider.SaveChanges(saveBundle);
    }

我发现被接管的东西太多了!(如果您不同意,请嘲笑我。)我的问题是:

  1. 我可以createEntity然后saveChanges吗?我只有一个空表格要填写和提交。当然没有必要items在客户端构建一个完整的阵列。

  2. 我可以将输入视图模型作为 a 传递JObject并在调用之前进行一些服务器端处理_contextProvider.SaveChanges()吗?


原来又是一篇超长的帖子。感谢您通读。真的很感激!

4

1 回答 1

5

好问题。不幸的是,我们的演示代码似乎掩盖了 Breeze 在客户端和服务器上的真正功能。Breeze 不受您恐惧的方式的限制。

我不想重复我们文档中的所有内容。我们确实在谈论这些问题。我们需要更多的例子来确定。

您正在描述 CQRS 设计。我认为它使大多数应用程序过于复杂。但这是你的特权。

如果你想发送ItemViewModel而不是Item,你可以。如果您希望将其视为 Breeze 客户端上的实体 -EntityManager将其转换为 KO 可观察对象并在缓存中对其进行管理、更改跟踪、验证它 - 您必须为其提供元数据......在服务器或客户端上。Breeze 也是如此……以及您可以命名的所有其他系统(Ember、Backbone 等)。很快,我们将更容易在服务器上为任意 CLR 模型创建元数据;这可能会有所帮助。

您可以完全控制服务器上的查询,顺便说一句,无论ItemItemViewModel. 您不必公开任何一个开放式查询。您似乎通过第二个示例查询知道这一点。

指挥部

您写道:“ [示例] 使用 ko.observableArray() 存储所有域模型数据,比如说 vm.items

这并不完全正确。您在示例中看到的 items 数组是为了演示而存在的。从 Breeze 的角度来看,items 数组不存储任何内容。事实上,在一次查询之后,查询响应中返回的实体(如果它们是实体)已经在管理器的缓存中,无论您对查询结果做什么,无论是放入数组还是丢弃它们。数组在经理对实体的跟踪中没有任何作用

你写道:“我可以createEntity然后saveChanges吗?

当然!该EntityManager.createEntity方法将新实体放入缓存中。同样,您看到它被推入items数组的原因是为了向用户展示。该数组与经理将保存的内容无关。

您写道:“我可以传递一个输入视图模型......并在调用之前进行一些服务器端处理_contextProvider.SaveChanges()吗?

我不知道您所说的“输入视图模型”是什么意思。微风EntityManager追踪实体。如果您的“输入视图模型”是一个实体,EntityManager则会跟踪它。如果它发生了变化并且您调用saveChanges了 ,管理器会将其发送到控制器的SaveChanges方法。

您拥有控制器SaveChanges方法的实现。JObject您可以使用更改集数据的 JSON.NET 表示来做任何您想做的事情。我认为您将受益于将ContextProvider对象解析为SaveMap. 阅读有关自定义 EFContextProvider 的主题。大多数人认为这提供了他们在将这些数据传递到数据访问层之前验证和操作客户端更改集数据所需的东西......无论是 EF 还是其他东西。

相反,如果您想创建自己的自定义 DTO 以 POST 到您自己的自定义控制器方法......请继续。不过不要打电话EntityManager.saveChanges。调用EntityManager.getChanges()并将更改的实体数组操作到您的 DTO 中。您将手动完成所有操作。但是你可以。就个人而言,我有更好的事情要做。

于 2013-03-08T21:10:51.857 回答