假设我们有两个表父“documentcodes”和子“documents”。
documentcodes表有DID、documentname、printOrder和ascordesc列
documents表有id、did和effectivedate列。我们通过连接这两个表来获取datatable。
我们需要根据以下规则对这个数据表进行排序。
按“打印顺序”列升序排序。
如果两行或多行具有类似的“documentnames”值,则根据“ascordesc”值按“effecivedate”升序或降序排序。
“ascordesc”列只接受“a”或“d”。如果值为“A”,我们需要对“有效日期”进行升序排序;如果值为“D”,我们需要对“有效日期”进行降序排序。
例如,
文件编码

 DID     DocumentName       PrintOrder      AscOrDesc
 1        Test1               1               D
 2        Test2               2               A
 3        Test3               3               D

文件
ID        DID        EffectiveDate
 1         2           7/9/2017
 2         1           5/5/2017
 3         2           7/8/2017
 4         3           4/9/2017

在把上面两张桌子连接起来之后。我们有数据表。
ID      DocumentName EffectiveDate  PrintOrder  AscOrDesc
1         Test2        7/9/2017       2          A
2         Test1        5/5/2017       1          D
3         Test2        7/8/2017       2          A
4         Test3        4/9/2017       3          D

在使用上述规则对这个数据表进行排序之后。数据表应该是这样的。
ID      DocumentName EffectiveDate  PrintOrder  AscOrDesc
1         Test1         5/5/2017      1           D
2         Test2         7/8/2017      2           A
3         Test2         7/9/2017      2           A
4         Test3         4/9/2017      3           D

注:生效日期为mm/dd/yyyy格式。
我试过使用下面的代码,但它不起作用。
var records2 = from q in datatable.AsEnumerable()
               let sortorder= q.Field<string>("AscOrDesc") == "A" ?
               "q.Field<DateTime>(\"EffectiveDate\") ascending":
               "q.Field<DateTime>(\"EffectiveDate\") descending"
               orderby q.Field<int>("PrintOrder"),sortorder
               select q;

我在上面的代码中做错了什么?

最佳答案

这种情况相当糟糕,因为理论上可以比较两个PrintOrder值相同但AscOrDesc值不同的结果行。只是数据的来源阻止了这一点。
我有一个可怕的黑客,我认为应该工作,但我真的不自豪。基本上,假设日期是一个数字…按降序日期排序等同于按“日期编号”的反序排序。对于DateTime,我们可以取Ticks值,从而得到:

var records2 = from q in datatable.AsEnumerable()
               let ticks = q.Field<DateTime>("EffectiveDate").Ticks *
                   (q.Field<string>("AscOrDesc") == "A" ? 1 : -1)
               orderby q.Field<int>("PrintOrder"), ticks
               select q;

丑死了,但它应该有用…

10-05 20:36