如何向Dynamic LINQ查询添加静态列并后续修改动态属性值
问题原因
Dynamic LINQ 的 ToDynamicListAsync() 返回的动态对象是内部 DynamicClass 类的实例,这个类不支持运行时新增属性,且没有实现索引器,所以你直接用 listEntry["MyAdditionalProp1"] 赋值,或者给实例加未预先定义的属性,都会失效。
解决方案
方案1:查询后转ExpandoObject(适合额外属性查询后才能确定的场景)
ExpandoObject 支持动态增删属性,同时兼容动态访问和索引器访问,你只需要把查询返回的原有属性复制过去即可:
List<dynamic> mutableClientData = new List<dynamic>(); foreach (dynamic entry in clientData) { IDictionary<string, object> expando = new ExpandoObject(); // 复制原有查询出来的所有属性 foreach (var prop in entry.GetType().GetProperties()) { expando[prop.Name] = prop.GetValue(entry); } // 直接添加额外属性,索引器、点访问都可以用 expando["MyAdditionalProp1"] = GetStringValue1(); expando.MyAdditionalProp2 = GetStringValue2(); mutableClientData.Add(expando); }
这个方案不需要修改原有查询逻辑,对现有代码侵入最小。如果你的额外属性是动态生成的,直接用属性名作为key往expando里加即可。
方案2:在Select中预先定义属性(适合额外属性查询前就已知的场景)
你原本的思路是可行的,之前失效是因为你用了索引器赋值,DynamicClass 实例直接用动态属性访问即可赋值:
// 动态生成额外属性的查询片段,不需要硬编码属性名 var extraColumns = new List<string> { "MyAdditionalProp1", "MyAdditionalProp2" } .Select(propName => $"'' AS {propName}"); // 拼接所有列:原有需要的列 + 预先定义的额外属性列 var allSelectColumns = requiredColumns.Concat(extraColumns); List<dynamic> clientData = await clientDataset .Select($"new({string.Join(",", allSelectColumns)})") .ToDynamicListAsync(); // 后续直接用点访问属性赋值即可 foreach (dynamic listEntry in clientData) { listEntry.MyAdditionalProp1 = GetStringValue1(); listEntry.MyAdditionalProp2 = GetStringValue2(); }
这个方案不需要做额外的对象转换,性能最好。
内容的提问来源于stack exchange,提问作者André Reichelt
相关产品推荐
相关产品推荐

