Asp.net mvc 4 如何在BreezeController中调用SaveChanges()?

Asp.net mvc 4 如何在BreezeController中调用SaveChanges()?,asp.net-mvc-4,knockout.js,asp.net-web-api,breeze,Asp.net Mvc 4,Knockout.js,Asp.net Web Api,Breeze,似乎所有现有的breezejs示例都在向BreezeController传递实体模型 但我们构建的几乎所有页面都使用某种形式的视图模型。在没有BreezeJs的日子里,我们从存储库中检索数据(域模型)以填充(使用AutoMapper或手动)视图模型,该视图模型只包含该视图所需的数据。WebAPI只将视图模型数据发送到浏览器,我们可以在浏览器中填充客户端视图模型(通常是剔除可见) 保存数据时,我们从收集数据以填充输入视图模型,仅将该数据发送到服务器,其中输入视图模型中的数据映射到域模型。通过在存储

似乎所有现有的breezejs示例都在向
BreezeController
传递实体模型

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

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

现在,
BreezeJs
将通过创建一个
EFContextProvider
来接管我们所有的存储库代码。我看到的示例通常检索域模型数据,然后将其全部传递给客户端

[HttpGet]
    public IQueryable<Item> Items() {
        return _contextProvider.Context.Items;
    }
我发现有太多的事情被接管了!(如果你不同意,就嘲笑我。)我的问题是:

  • 我可以只
    createEntity
    然后
    saveChanges
    吗? 我只有一张空表格要填写和提交。当然,不需要在客户端构建一个完整的
    items
    数组

  • 在调用
    \u contextProvider.SaveChanges()
    之前,是否可以将输入视图模型作为
    作业对象传递并执行一些服务器端处理



  • 结果又是一篇很长的帖子。谢谢你通读。真的很感激

    好问题。不幸的是,我们的演示代码似乎掩盖了Breeze在客户端和服务器上的真正功能。微风并没有束缚你的恐惧

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

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

    如果要发送
    ItemViewModel
    而不是
    Item
    ,可以。如果您希望将其作为Breeze客户端上的一个实体处理-让
    EntityManager
    将其转换为一个可观察的KO,并在缓存中管理它,更改跟踪它,验证它-,您必须为它提供元数据。。。在服务器或客户端上。这对微风来说是真的。。。以及您可以命名的所有其他系统(余烬、主干网等)。很快,我们将更容易在服务器上为任意CLR模型创建元数据;这可能会有帮助

    顺便说一句,您可以完全控制服务器上的查询,无论是
    Item
    还是
    ItemViewModel
    。您不必为这两种方法公开开放式查询。通过第二个示例查询,您似乎知道这一点

    命令一侧

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

    事实并非如此。您在示例中看到的items数组用于演示。从Breeze的角度来看,items数组没有存储任何内容。事实上,在查询之后,查询响应中返回的实体(如果它们是实体)已经在管理器的缓存中,不管您对查询结果做了什么,不管您是将它们放入数组还是将它们丢弃阵列在管理者跟踪实体时不起任何作用

    您写道:“我可以只
    createEntity
    然后
    saveChanges
    ?”

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

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

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

    您拥有控制器的
    SaveChanges
    方法的实现。您可以使用
    JObject
    做任何您想做的事情,它只是变更集数据的JSON.NET表示形式。我认为
    ContextProvider
    将该对象解析为
    SaveMap
    的工作将使您受益匪浅。读这本书。大多数人认为这提供了在将客户机更改集数据传递到数据访问层之前验证和操作这些数据所需的功能。。。不管是EF还是其他什么

    如果您想创建自己的自定义DTO以发布到自己的自定义控制器方法。。。请说吧。但不要调用EntityManager.saveChanges
    。调用
    EntityManager.getChanges()
    并将实体数组更改为DTO。一切都是你亲手做的。但是你可以。就我个人而言,我有更好的事情要做

    [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;
    }
    
        [HttpPost]
        public SaveResult SaveChanges(JObject saveBundle) {
            return _contextProvider.SaveChanges(saveBundle);
        }