使用动态 LINQ 按一个或多个属性对 JSON 进行排序
Posted
技术标签:
【中文标题】使用动态 LINQ 按一个或多个属性对 JSON 进行排序【英文标题】:Sort JSON by one or more properties using Dynamic LINQ 【发布时间】:2014-11-28 01:23:49 【问题描述】:我有一些 JSON 需要在 C# 中进行排序。我正在尝试使用System.Linq.Dynamic
对JObject
s 列表进行排序,但我无法让它与Newtonsoft.Json.Linq.JObject
的实例一起使用。
这行得通:
public class Row
public String Column1 get; set;
public Int32 Column2 get; set;
var rows = new List<Row>();
rows.Add(new Row Column1 = "B", Column2 = 2 );
rows.Add(new Row Column1 = "B", Column2 = 1 );
rows.Add(new Row Column1 = "A", Column2 = 2 );
rows.Add(new Row Column1 = "A", Column2 = 1 );
var sortedRows = rows.AsQueryable().OrderBy("Column1, Column2");
这不是:
var rows = new List<JObject>();
var row1 = new JObject();
row1["Column1"] = "B";
row1["Column2"] = 2;
rows.Add(row1);
var row2 = new JObject();
row2["Column1"] = "B";
row2["Column2"] = 1;
rows.Add(row2);
var row3 = new JObject();
row3["Column1"] = "A";
row3["Column2"] = 2;
rows.Add(row3);
var row4 = new JObject();
row4["Column1"] = "A";
row4["Column2"] = 1;
rows.Add(row4);
var sortedRows = rows.AsQueryable().OrderBy("Column1, Column2");
//System.Linq.Dynamic.ParseException : No property or field 'Column1' exists in type 'JObject'
如何根据动态数量的属性对 JObject
实例进行排序?
【问题讨论】:
【参考方案1】:您可以使用来自System.Dynamic.Linq
的索引器语法:
var sortedRows = rows.AsQueryable().OrderBy(@"it[""Column1""], it[""Column2""]");
旧答案
您无法使用System.Linq.Dynamic
执行此操作。要访问JObject
的属性,您需要调用Property
方法。但是,System.Linq.Dynamic
不允许这样做。来自文档:
表达式语言将方法和构造函数的调用限制为在可访问类型中声明为公共的那些。
表达式语言定义了以下原始类型:
Object Boolean Char String SByte Byte Int16 UInt16 Int32 UInt32 Int64 UInt64 Decimal Single Double DateTime TimeSpan Guid
原始类型对应于 .NET Framework 基类库的 System 命名空间中类似命名的类型。表达式语言还定义了一组可访问类型,由原始类型和 System 命名空间中的以下类型组成:
Math Convert
可访问类型是唯一可以在表达式中显式引用的类型,表达式语言中的方法调用仅限于在可访问类型中声明的方法。
【讨论】:
这太完美了!使我免于实施可怕的黑客攻击。【参考方案2】:您可以像这样实现自己的IComparer
:
public class MyJObjectComparer : IComparer<JObject>
public int Compare(JObject a, JObject b)
if ((a["Column1"] == b["Column1"]) && a["Column2"] == b["Column2"]))
return 0;
if ((a["Column1"] < b["Columnq"]) || ((a["Column1"] == b["Column1"]) && (a["Column2"] < b["Column2"])))
return -1;
return 1;
并像这样使用它:
var sortedRows = rows.AsQueryable().OrderBy(r => r, new MyJObjectComparer());
【讨论】:
以上是关于使用动态 LINQ 按一个或多个属性对 JSON 进行排序的主要内容,如果未能解决你的问题,请参考以下文章