我的DTO A包含一个List实体.所以我可以预测A内的元素.
再次:
- class A
- {
- someprop;
- List<B> childB;
- }
- Class B
- {
- somepropB;
- }
到现在为止还挺好.我可以毫无问题地迭代数据.
但是如果我在A和SaveAll的实例中更改“someprop”,服务器根本不会响应.
甚至不调用updateData控件方法.
如果我在将childB.Clear()发送到客户端之前清除它,一切都很好.
看起来结果是无法用集合更新实体?
解决方法
解决方案是手动映射实体.为了让我的生活更轻松,我在下面的代码片段中使用了我的“DeliveryTracker”示例应用程序中的代码.在我的博客文章中,您可以看到手动映射的示例:http://bartjolling.blogspot.com/2012/04/building-single-page-apps-with-aspnet.html所以我的下面的示例正在处理“交付”和“客户”对象.
服务器端域模型
- 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; }
- }
- }
数据服务控制器
数据服务控制器公开符合OData标准的数据
的 “http://本地主机:[yourport] / API / DataService的/ GetCustomers的”.为了能够更新客户和交付,您需要定义UpdateCustomer和UpdateDelivery函数
- 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对象的构造函数中的行,我将传入的交付映射到可观察的数组中
- /// <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中初始化Upshot,指定自定义客户端映射并绑定viewmodel
- @(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”属性绑定的复选框进行预先修复.客户的名称也是可编辑的,因为它绑定到INPUT元素
我没有足够的声誉来发布截图,所以你必须没有它
现在选中或取消选中IsDelivered复选框时,Upshot将检测更改并将其发布到DataService Controller
- [{"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","IsDelivered":false
- }
- }]
- [{
- "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","Name": "Rich Feynmann"
- }
- }]
因此,如果您按照上述步骤操作,Upshot将为您更新父实体和子实体.