OData DataServiceQuery仅返回集合最后一项问题求助
OData客户端反序列化关联集合丢失数据的解决方法
问题场景
我通过Visual Studio OData连接服务向导为OData 2.0服务器生成了DataService客户端。调用接口获取数据时,服务器返回ORDERITEM集合的10条关联数据,但反序列化后的集合仅保留最后一条数据。经排查发现,OrderItem类的DataServiceKeyAttribute被设置为关联父类的OrderNumber字段,而服务器返回的所有OrderItem项的OrderNumber值均相同。
相关代码片段:
OrderItem类定义
[global::System.Data.Services.Common.DataServiceKeyAttribute("OrderNumber")] public partial class OrderItem : global::System.ComponentModel.INotifyPropertyChanged
数据查询代码
var bct = new ZZ_Entities( new Uri(server + "ZZ_SRV")); var query = bct.OrderSet.Expand(ogh => ogh.ORDERITEM) .Where( x=> x.OrderNumber == orderNumber).Select(oss => oss); DataServiceQuery<Order> osQquery = (DataServiceQuery<Order>)query; TaskFactory<IEnumerable<Order>> taskFactory = new TaskFactory<IEnumerable<Order>>(); IEnumerable<OrderGetHeader> result = await taskFactory.FromAsync( osQquery.BeginExecute(null, null), iar => osQquery.EndExecute(iar));
原因分析
DataServiceKeyAttribute用于标记OData实体的唯一标识键。当多个OrderItem实例的OrderNumber值相同时,客户端会判定这些实例为同一个实体,后续实例会覆盖之前的,最终只保留最后一条数据。
解决方案
修改OrderItem类的DataServiceKeyAttribute,指定OrderItem自身的唯一标识字段(或复合字段):
方案1:使用单唯一键
如果OrderItem有自身的唯一字段(如OrderItemId),直接替换:
// 在单独的partial类文件中定义,避免自动生成覆盖 [global::System.Data.Services.Common.DataServiceKeyAttribute("OrderItemId")] public partial class OrderItem : global::System.ComponentModel.INotifyPropertyChanged { // 无需重复定义其他成员,partial类会自动合并 }
方案2:使用复合键
如果OrderItem没有单独的唯一键,可组合OrderNumber和另一个区分字段(如LineItemNumber)作为复合键:
// 在单独的partial类文件中定义 [global::System.Data.Services.Common.DataServiceKeyAttribute("OrderNumber", "LineItemNumber")] public partial class OrderItem : global::System.ComponentModel.INotifyPropertyChanged { }
注意:不要直接修改Visual Studio自动生成的类文件,否则重新生成OData服务时修改会被覆盖。通过新建partial类文件的方式修改属性,能保证修改持久化。
内容的提问来源于stack exchange,提问作者Aaron Fischer
相关产品推荐
相关产品推荐

