Microsoft.OData.Client 7.1如何仅提交嵌套对象的变更属性?
解决SAP B1 Service Layer OData客户端嵌套实体全量提交问题
核心原因
SaveChangesOptions.PostOnlySetProperties默认仅对顶层实体生效,嵌套的子实体/集合如果未被上下文正确跟踪变更状态,会被当作完整对象提交(包含所有空值属性)。
解决方案
1. 用DataServiceCollection管理嵌套订单行集合
不要直接向salesOrder.DocumentLines添加订单行,而是将子集合也包装为DataServiceCollection,让OData上下文跟踪子实体的属性变更:
var salesOrder = new Document { // 设置订单必填属性,比如CardCode、DocDate等 CardCode = "C0001", DocDate = DateTime.Now }; // 初始化顶层订单的DataServiceCollection var orderCollection = new DataServiceCollection<Document>(context, nameof(context.Orders), null, null); orderCollection.Add(salesOrder); // 初始化订单行的DataServiceCollection,关联父订单与上下文 var lineCollection = new DataServiceCollection<DocumentLine>(context, salesOrder, nameof(Document.DocumentLines), null, null); var orderLine = new DocumentLine { // 设置订单行必填属性,比如ItemCode、Quantity等 ItemCode = "I0001", Quantity = 10 }; lineCollection.Add(orderLine); // 提交变更,此时子实体仅发送已设置的属性 var response = await context.SaveChangesAsync(SaveChangesOptions.PostOnlySetProperties);
2. 手动标记子实体的已设置属性
如果自动生成的DocumentLine类未自动触发变更跟踪(比如属性setter未调用变更通知方法),需要手动调用上下文的SetProperty方法标记已修改的属性:
// 在创建订单行并设置属性后,手动标记 context.SetProperty(orderLine, nameof(orderLine.ItemCode), orderLine.ItemCode); context.SetProperty(orderLine, nameof(orderLine.Quantity), orderLine.Quantity);
3. 检查生成实体的变更跟踪接口
确保自动生成的实体类实现了INotifyPropertyChanged或ITrackOriginalValues接口,这是OData上下文识别属性变更的基础。如果生成代码时未启用相关选项,需重新生成客户端并勾选"Enable change tracking"类的配置项。
内容的提问来源于stack exchange,提问作者kavanka
相关产品推荐
相关产品推荐

