首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何通过MVC4 upshot上传相关实体

如何通过MVC4 upshot上传相关实体
EN

Stack Overflow用户
提问于 2012-03-27 19:38:11
回答 1查看 2.3K关注 0票数 1

我将一个简单的DTO实体A加载到我的upshot视图模型中,它可以通过Knockoutjs查看。

我的DTO包含一个实体列表。所以我可以遍历A内部的元素。

再一次:

代码语言:javascript
复制
class A
    {
       someprop;
        List<B> childB;
    }
Class B
{
   somepropB;
}

到目前一切尚好。我可以毫无问题地迭代数据。但是,如果我在A和SaveAll的实例中更改了"someprop“,服务器将根本不会响应。甚至不调用updateData控件方法。如果我在将childB.Clear()传输到客户机之前清除它,一切都是正常的。

似乎结果是不能用集合更新实体?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-04-04 20:03:35

如果您想要这样的场景工作,还有一些工作要做。结果仅在可观察的项目中翻转父实体。因此,只有类A的javascript表示是击倒可观察的,而类B的javascript表示不是。因此,Upshot不知道关联对象中的任何更改。

解决方案是手动映射实体。为了让我的生活更轻松,我在下面的代码片段中使用了我的'DeliveryTracker‘示例应用程序中的代码。在我的博客文章中,你可以看到一个手动映射的例子:http://bartjolling.blogspot.com/2012/04/building-single-page-apps-with-aspnet.html,所以我下面的例子是处理'delivery‘和'customer’对象。

服务器端域模型

代码语言:javascript
复制
namespace StackOverflow.q9888839.UploadRelatedEntities.Models
{
    public class Customer
    {
        [Key]
        public int CustomerId { get; set; }

        public string Name { get; set; }
        public string Address { get; set; }
        public double Latitude { get; set; }
        public double Longitude { get; set; }

        public virtual ICollection<Delivery> Deliveries { get; set; }
    }

    public class Delivery
    {
        [Key]
        public int DeliveryId { get; set; }
        public string Description { get; set; }
        public bool IsDelivered { get; set; }

        [IgnoreDataMember] //needed to break cyclic reference
        public virtual Customer Customer { get; set; }
        public virtual int CustomerId { get; set; }
    }

    public class AppDbContext : DbContext
    {
        public DbSet<Customer> Customers { get; set; }
        public DbSet<Delivery> Deliveries { get; set; }
    }
}

数据业务控制器

数据服务控制器在"http://localhost:[yourport]/api/dataservice/GetCustomers"“上公开符合OData标准的数据。为了能够更新客户和交付,您需要定义一个UpdateCustomer和UpdateDelivery函数

代码语言:javascript
复制
namespace StackOverflow.q9888839.UploadRelatedEntities.Controllers
{
    public class DataServiceController : DbDataController<AppDbContext>
    {
        //Service interface for Customer
        public IQueryable<Customer> GetCustomers()
        {
            return DbContext.Customers.Include("Deliveries").OrderBy(x => x.CustomerId);
        }
        public void InsertCustomer(Customer customer) { InsertEntity(customer); }
        public void UpdateCustomer(Customer customer) { UpdateEntity(customer); }
        public void DeleteCustomer(Customer customer) { DeleteEntity(customer); }

        //Service interface for Deliveries
        public void InsertDelivery(Delivery delivery) { InsertEntity(delivery); }
        public void UpdateDelivery(Delivery delivery) { UpdateEntity(delivery); }
        public void DeleteDelivery(Delivery delivery) { DeleteEntity(delivery); }
    }
}

客户端域模型

添加一个包含客户端模型的新javascript文件。在这里,我显式地将每个属性转换为击倒可见对象。解决问题的关键是Customer对象的构造函数中的行,我在这里将传入的交付映射到一个可观察的数组中

代码语言:javascript
复制
/// <reference path="_references.js" />
(function (window, undefined) {

    var deliveryTracker = window["deliveryTracker"] = {}; //clear namespace

    deliveryTracker.DeliveriesViewModel = function () {
        // Private
        var self = this;
        self.dataSource = upshot.dataSources.Customers;
        self.dataSource.refresh();
        self.customers = self.dataSource.getEntities();
    };

    deliveryTracker.Customer = function (data) {
        var self = this;

        self.CustomerId = ko.observable(data.CustomerId);
        self.Name = ko.observable(data.Name);
        self.Address = ko.observable(data.Address);
        self.Latitude = ko.observable(data.Latitude);
        self.Longitude = ko.observable(data.Longitude);

        self.Deliveries = ko.observableArray(ko.utils.arrayMap(data.Deliveries, function (item) {
            return new deliveryTracker.Delivery(item);
        }));

        upshot.addEntityProperties(self, "Customer:#StackOverflow.q9888839.UploadRelatedEntities.Models");
    };

    deliveryTracker.Delivery = function (data) {
        var self = this;

        self.DeliveryId = ko.observable(data.DeliveryId);
        self.CustomerId = ko.observable(data.CustomerId);
        self.Customer = ko.observable(data.Customer ? new deliveryTracker.Customer(data.Customer) : null);
        self.Description = ko.observable(data.Description);
        self.IsDelivered = ko.observable(data.IsDelivered);

        upshot.addEntityProperties(self, "Delivery:#StackOverflow.q9888839.UploadRelatedEntities.Models");
    };

    //Expose deliveryTracker to global
    window["deliveryTracker"] = deliveryTracker;
})(window);

视图

在初始化结论的index.cshtml中,指定自定义客户端映射并绑定视图模型

代码语言:javascript
复制
@(Html.UpshotContext(bufferChanges: false)
              .DataSource<StackOverflow.q9888839.UploadRelatedEntities.Controllers.DataServiceController>(x => x.GetCustomers())
              .ClientMapping<StackOverflow.q9888839.UploadRelatedEntities.Models.Customer>("deliveryTracker.Customer")
              .ClientMapping<StackOverflow.q9888839.UploadRelatedEntities.Models.Delivery>("deliveryTracker.Delivery")
)
<script type="text/javascript">
    $(function () {
        var model = new deliveryTracker.DeliveriesViewModel();
        ko.applyBindings(model);
    });
</script>

<section>
<h3>Customers</h3>
    <ol data-bind="foreach: customers">
        <input data-bind="value: Name" />

        <ol data-bind="foreach: Deliveries">
            <li>
                <input type="checkbox" data-bind="checked: IsDelivered" >
                    <span data-bind="text: Description" /> 
                </input>
            </li>
        </ol>
    </ol>
</section>

结果

导航到索引页时,将异步加载客户和相关交付的列表。所有的交付都是按客户分组的,并且预先固定了一个与交付的“IsDelivered”属性绑定的复选框。客户的名字也是可编辑的,因为它绑定到一个输入元素

我没有足够的声誉来发布截图,所以你将不得不没有一个截图

当现在选中或取消选中IsDelivered复选框时,DataService将检测到更改并将其发布到Upshot控制器

代码语言:javascript
复制
[{"Id":"0",
    "Operation":2,
    "Entity":{
        "__type":"Delivery:#StackOverflow.q9888839.UploadRelatedEntities.Models",
        "CustomerId":1,
        "DeliveryId":1,
        "Description":"NanoCircuit Analyzer",
        "IsDelivered":true
    },
    "OriginalEntity":{
        "__type":"Delivery:#StackOverflow.q9888839.UploadRelatedEntities.Models",
        "CustomerId":1,
        "DeliveryId":1,
        "Description":"NanoCircuit Analyzer",
        "IsDelivered":false
    }
}]

修改客户名称时,当输入框失去焦点时,Upshot将提交更改

代码语言:javascript
复制
[{
    "Id": "0",
    "Operation": 2,
    "Entity": {
        "__type": "Customer:#StackOverflow.q9888839.UploadRelatedEntities.Models",
        "Address": "Address 2",
        "CustomerId": 2,
        "Latitude": 51.229248,
        "Longitude": 4.404831,
        "Name": "Richie Rich"
    },
    "OriginalEntity": {
         "__type": "Customer:#StackOverflow.q9888839.UploadRelatedEntities.Models",
        "Address": "Address 2",
        "CustomerId": 2,
        "Latitude": 51.229248,
        "Longitude": 4.404831,
        "Name": "Rich Feynmann"
    }
}]

因此,如果您遵循上述步骤,Upshot将为您更新父实体和子实体。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9888839

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档