2014-10-02 55 views
3

我有一些JSON需要在C#中排序。我试图使用System.Linq.DynamicJObject s列表进行排序,但我无法使其与Newtonsoft.Json.Linq.JObject的实例一起使用。使用动态LINQ对一个或多个属性排序JSON

这工作:

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基础类库的系统命名空间。表达式语言还定义了一组访问类型组成的原始类型和以下类型的从系统的名称空间:

Math Convert

的可访问类型是可以在表达式中明确引用的唯一类型,并且表达式语言中的方法调用仅限于在可访问类型中声明的方法。

+0

这是完美的!使我免于实施可怕的黑客攻击。 – tponthieux 2014-10-03 00:20:17

1

你可以实现自己的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());