假设我们有两个表Parent" DocumentCodes"和孩子"文件"。 DocumentCodes表包含列DID,DocumentName,PrintOrder和AscOrDesc Documents表有列ID,DID和EffectiveDate。我们通过连接这两个表来获取数据表。
我们需要根据以下规则对此数据表进行排序。
例如,
DocumentCodes
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
加入以上两个表后。我们有DataTable。
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
现在使用上述规则对此DataTable进行排序。 DataTable应如下所示。
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
注意:EffectiveDate采用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;
我在上面的代码中做错了什么?
答案 0 :(得分:3)
这种情况相当丑陋,因为理论上可以比较两个具有相同PrintOrder
但不同AscOrDesc
值的结果行。它只是防止这种情况的数据来源。
我确实有一个可怕的黑客,我认为应该有效,但我真的不为此感到骄傲。基本上,假设日期是一个数字......按降序排序相当于通过否定&#34;日期编号&#34;来排序。对于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;
丑陋,但它应该有用......
答案 1 :(得分:2)
非常难看,但无法找到更符合您需求的东西。 也许你有运气,而且@JonSkeet会再来一次。 :)
(使用LINQ To Object,你需要重写它适合你的LINQ to SQL)
static void Main(string[] args)
{
var lstFoos = new List<Foo>() {
new Foo() { Id = 1, DocumentName = "Test2", EffectiveDate = new DateTime(2017, 7, 9), PrintOrder = 2, AscOrDesc = "A" },
new Foo() { Id = 2, DocumentName = "Test1", EffectiveDate = new DateTime(2017, 5, 5), PrintOrder = 1, AscOrDesc = "D" },
new Foo() { Id = 3, DocumentName = "Test2", EffectiveDate = new DateTime(2017, 7, 8), PrintOrder = 2, AscOrDesc = "A" },
new Foo() { Id = 4, DocumentName = "Test3", EffectiveDate = new DateTime(2017, 4, 9), PrintOrder = 3, AscOrDesc = "D" },
};
var result = lstFoos.OrderBy(x => x.PrintOrder).GroupBy(x => x.DocumentName).SelectMany(x =>
{
if (x.Count() > 1)
{
var ascOrDesc = x.First().AscOrDesc;
return new List<Foo>(ascOrDesc == "A" ? x.OrderBy(y => y.EffectiveDate) : x.OrderByDescending(y => y.EffectiveDate));
}
return new List<Foo>() {x.First()};
});
foreach (var foo in result)
Console.WriteLine(foo.ToString());
Console.ReadLine();
}
public class Foo
{
public int Id { get; set; }
public string DocumentName { get; set; }
public DateTime EffectiveDate { get; set; }
public int PrintOrder { get; set; }
public string AscOrDesc { get; set; }
public override string ToString()
{
return $"Id: {Id} | DocumentName: {DocumentName} | EffectiveDate: {EffectiveDate} | PrintOrder: {PrintOrder} | AscOrDesc: {AscOrDesc}";
}
}
答案 2 :(得分:0)
看起来像一个TYPO,希望这个工作
var records2 = from q in datatable.AsEnumerable()
orderby q.Field<int>("PrintOrder")
orderby q.Field<string>("AscOrDesc") == "A" ? q.Field<DateTime>("EffectiveDate") : q.Field<DateTime>("EffectiveDate") descending
select q;
通常我的陈述曾经是这样的
var result = from q in datatable.AsEnumerable()
orderby q.PrintOrder
orderby q.AscOrDesc== "A" ? q.EffectiveDate: q.EffectiveDate descending
select q;