来自多个列和表的linq最大日期
linq max date from multiple columns and tables
Objective:table1
、table2
、table3
每个日期列都有多个不同名称的日期列。
我需要为相应的 Id 拉回这些列的最大日期;最后修改日期。
我可以构建一个数组形式的 let 变量,然后选择最大值吗?
或者我需要在查询中做一些 case 语句吗?
我所做的每一次尝试都失败了,寻求建议....
var query = from t1 in table1
join t2 in table2
on t1.Id equals t2.Id
join t3 in table3
on t1.Id equals t3.Id
select new
{
Id = t1.Id
LastModified = <max date from multiple columns from different tables>
};
您可以将表转换为通用类型,然后取最大日期。
var list1 = new List<Table1>();
var list2 = new List<Table2>();
var list3 = new List<Table3>();
var lastRecord = list1.Select(x => new {Id = x.Id, DateTime = x.Dt})
.Union(list2.Select(x => new {Id = x.Id2, DateTime = x.Date}))
.Union(list3.Select(x => new {Id = x.Id3, DateTime = x.DateDiffName}))
.OrderByDescending(t => t.DateTime)
.First();
使用@Alexander 的方法,并将您的查询切换到 Lambda/Fluent LINQ 语法,因为 Union
在查询语法中不(直接)可用。
首先,从要比较的每个 table 中取出所有日期列,并将它们展平成单独的行:
var t1Dates = table1.Select(t1 => new { t1.Id, DT = t1.dc1 })
.Union(table1.Select(t1 => new { t1.Id, DT = t1.dc2 }));
var t2Dates = table2.Select(t2 => new { t2.Id, DT = t2.t2dc1 })
.Union(table2.Select(t2 => new { t2.Id, DT = t2.t2dc2 }));
var t3Dates = table3.Select(t3 => new { t3.Id, DT = t3.t3dc1 })
.Union(table3.Select(t3 => new { t3.Id, DT = t3.t3dc2 }));
然后,像最初那样加入单独的日期:
var t123Dates = t1Dates.Join(t2Dates, t1 => t1.Id, t2 => t2.Id, (t1, t2) => new { t1.Id, DT1 = t1.DT, DT2 = t2.DT })
.Join(t3Dates, t12 => t12.Id, t3 => t3.Id, (t12, t3) => new { t12.Id, t12.DT1, t12.DT2, DT3 = t3.DT });
然后,将连接的值展平到不同的行中:
var tAllDates = t123Dates.Select(t123 => new { t123.Id, DT = t123.DT1 })
.Union(t123Dates.Select(t123 => new { t123.Id, DT = t123.DT2 }))
.Union(t123Dates.Select(t123 => new { t123.Id, DT = t123.DT3 }));
最后,您可以按 Id
对扁平化结果进行分组,并找到每个 Id
:
对应的最新日期
var query = tAllDates.GroupBy(ta => ta.Id)
.Select(tag => new {
Id = tag.Key,
LastModified = tag.OrderByDescending(ta => ta.DT).First().DT
});
如果您只对 Id
和 LastModified Date
感兴趣,我的建议是使用 Select
到 select Id
和Date
,然后 Orderby
降序日期并取第一个:
var result = dbContext.Table1.Select(row => new
{
Id = row.Id,
Date = row.Date,
})
.Concat(dbContext.Table2.Select(row => new
{
Id = row.Id,
Date = row.Date,
})
.Concat(dbContext.Table3.Select(row => new
{
Id = row.Id,
Date = row.Date,
})
.OrderByDescending(row => row.Date)
.FirstOrDefault();
简而言之:从表 1 的每一行中获取 ID 和日期。对 table2 和 table3 中的行执行类似的操作。将这些 selected 项一个接一个地放置,按数据降序排列,取第一个,如果根本没有行,则为 null。
简单的comme bonjour!
根据我的理解,我创建了以下代码。请看一看。代码本身包含注释:
static void LinkDate()
{
DataTable table1 = new DataTable();
table1.Columns.Add("Id");
table1.Columns.Add("Date", typeof(System.DateTime));
DataTable table2 = new DataTable();
table2.Columns.Add("Id");
table2.Columns.Add("Date", typeof(System.DateTime));
DataTable table3 = new DataTable();
table3.Columns.Add("Id");
table3.Columns.Add("Date", typeof(System.DateTime));
DataRow row = table1.NewRow();
row[0] = "1";
row[1] = Convert.ToDateTime("01/22/2020");
table1.Rows.Add(row);
row = table1.NewRow();
row[0] = "2";
row[1] = Convert.ToDateTime("01/23/2020");
table1.Rows.Add(row);
row = table1.NewRow();
row[0] = "3";
row[1] = Convert.ToDateTime("02/22/2020");
table1.Rows.Add(row);
row = table1.NewRow();
row[0] = "4";
row[1] = Convert.ToDateTime("03/22/2020");
table1.Rows.Add(row);
row = table1.NewRow();
row[0] = "5";
row[1] = Convert.ToDateTime("05/22/2020");
table1.Rows.Add(row);
row = table2.NewRow();
row[0] = "1";
row[1] = Convert.ToDateTime("01/25/2020");
table2.Rows.Add(row);
row = table2.NewRow();
row[0] = "2";
row[1] = Convert.ToDateTime("04/21/2020");
table2.Rows.Add(row);
row = table2.NewRow();
row[0] = "3";
row[1] = Convert.ToDateTime("02/11/2020");
table2.Rows.Add(row);
row = table2.NewRow();
row[0] = "8";
row[1] = Convert.ToDateTime("08/12/2020");
table2.Rows.Add(row);
row = table2.NewRow();
row[0] = "9";
row[1] = Convert.ToDateTime("02/25/2020");
table2.Rows.Add(row);
row = table3.NewRow();
row[0] = "1";
row[1] = Convert.ToDateTime("03/20/2020");
table3.Rows.Add(row);
row = table3.NewRow();
row[0] = "2";
row[1] = Convert.ToDateTime("01/11/2020");
table3.Rows.Add(row);
row = table3.NewRow();
row[0] = "12";
row[1] = Convert.ToDateTime("01/21/2020");
table3.Rows.Add(row);
row = table3.NewRow();
row[0] = "8";
row[1] = Convert.ToDateTime("09/22/2020");
table3.Rows.Add(row);
row = table3.NewRow();
row[0] = "11";
row[1] = Convert.ToDateTime("01/20/2020");
table3.Rows.Add(row);
var query = from t1 in table1.AsEnumerable()
join t2 in table2.AsEnumerable()
on t1.Field<string>("Id") equals t2.Field<string>("Id")
join t3 in table3.AsEnumerable()
on t1.Field<string>("Id") equals t3.Field<string>("Id")
select new
{
Id = t1.Field<string>("Id"),
LastModified = Max(t1.Field<DateTime>("Date"), t2.Field<DateTime>("Date"), t3.Field<DateTime>("Date"))
};
}
static DateTime Max(DateTime a, DateTime b, DateTime c)
{
//Get max value between three.
DateTime[] aa = { a, b, c };
return aa.Max();
}
Objective:table1
、table2
、table3
每个日期列都有多个不同名称的日期列。
我需要为相应的 Id 拉回这些列的最大日期;最后修改日期。
我可以构建一个数组形式的 let 变量,然后选择最大值吗?
或者我需要在查询中做一些 case 语句吗?
我所做的每一次尝试都失败了,寻求建议....
var query = from t1 in table1
join t2 in table2
on t1.Id equals t2.Id
join t3 in table3
on t1.Id equals t3.Id
select new
{
Id = t1.Id
LastModified = <max date from multiple columns from different tables>
};
您可以将表转换为通用类型,然后取最大日期。
var list1 = new List<Table1>();
var list2 = new List<Table2>();
var list3 = new List<Table3>();
var lastRecord = list1.Select(x => new {Id = x.Id, DateTime = x.Dt})
.Union(list2.Select(x => new {Id = x.Id2, DateTime = x.Date}))
.Union(list3.Select(x => new {Id = x.Id3, DateTime = x.DateDiffName}))
.OrderByDescending(t => t.DateTime)
.First();
使用@Alexander 的方法,并将您的查询切换到 Lambda/Fluent LINQ 语法,因为 Union
在查询语法中不(直接)可用。
首先,从要比较的每个 table 中取出所有日期列,并将它们展平成单独的行:
var t1Dates = table1.Select(t1 => new { t1.Id, DT = t1.dc1 })
.Union(table1.Select(t1 => new { t1.Id, DT = t1.dc2 }));
var t2Dates = table2.Select(t2 => new { t2.Id, DT = t2.t2dc1 })
.Union(table2.Select(t2 => new { t2.Id, DT = t2.t2dc2 }));
var t3Dates = table3.Select(t3 => new { t3.Id, DT = t3.t3dc1 })
.Union(table3.Select(t3 => new { t3.Id, DT = t3.t3dc2 }));
然后,像最初那样加入单独的日期:
var t123Dates = t1Dates.Join(t2Dates, t1 => t1.Id, t2 => t2.Id, (t1, t2) => new { t1.Id, DT1 = t1.DT, DT2 = t2.DT })
.Join(t3Dates, t12 => t12.Id, t3 => t3.Id, (t12, t3) => new { t12.Id, t12.DT1, t12.DT2, DT3 = t3.DT });
然后,将连接的值展平到不同的行中:
var tAllDates = t123Dates.Select(t123 => new { t123.Id, DT = t123.DT1 })
.Union(t123Dates.Select(t123 => new { t123.Id, DT = t123.DT2 }))
.Union(t123Dates.Select(t123 => new { t123.Id, DT = t123.DT3 }));
最后,您可以按 Id
对扁平化结果进行分组,并找到每个 Id
:
var query = tAllDates.GroupBy(ta => ta.Id)
.Select(tag => new {
Id = tag.Key,
LastModified = tag.OrderByDescending(ta => ta.DT).First().DT
});
如果您只对 Id
和 LastModified Date
感兴趣,我的建议是使用 Select
到 select Id
和Date
,然后 Orderby
降序日期并取第一个:
var result = dbContext.Table1.Select(row => new
{
Id = row.Id,
Date = row.Date,
})
.Concat(dbContext.Table2.Select(row => new
{
Id = row.Id,
Date = row.Date,
})
.Concat(dbContext.Table3.Select(row => new
{
Id = row.Id,
Date = row.Date,
})
.OrderByDescending(row => row.Date)
.FirstOrDefault();
简而言之:从表 1 的每一行中获取 ID 和日期。对 table2 和 table3 中的行执行类似的操作。将这些 selected 项一个接一个地放置,按数据降序排列,取第一个,如果根本没有行,则为 null。
简单的comme bonjour!
根据我的理解,我创建了以下代码。请看一看。代码本身包含注释:
static void LinkDate()
{
DataTable table1 = new DataTable();
table1.Columns.Add("Id");
table1.Columns.Add("Date", typeof(System.DateTime));
DataTable table2 = new DataTable();
table2.Columns.Add("Id");
table2.Columns.Add("Date", typeof(System.DateTime));
DataTable table3 = new DataTable();
table3.Columns.Add("Id");
table3.Columns.Add("Date", typeof(System.DateTime));
DataRow row = table1.NewRow();
row[0] = "1";
row[1] = Convert.ToDateTime("01/22/2020");
table1.Rows.Add(row);
row = table1.NewRow();
row[0] = "2";
row[1] = Convert.ToDateTime("01/23/2020");
table1.Rows.Add(row);
row = table1.NewRow();
row[0] = "3";
row[1] = Convert.ToDateTime("02/22/2020");
table1.Rows.Add(row);
row = table1.NewRow();
row[0] = "4";
row[1] = Convert.ToDateTime("03/22/2020");
table1.Rows.Add(row);
row = table1.NewRow();
row[0] = "5";
row[1] = Convert.ToDateTime("05/22/2020");
table1.Rows.Add(row);
row = table2.NewRow();
row[0] = "1";
row[1] = Convert.ToDateTime("01/25/2020");
table2.Rows.Add(row);
row = table2.NewRow();
row[0] = "2";
row[1] = Convert.ToDateTime("04/21/2020");
table2.Rows.Add(row);
row = table2.NewRow();
row[0] = "3";
row[1] = Convert.ToDateTime("02/11/2020");
table2.Rows.Add(row);
row = table2.NewRow();
row[0] = "8";
row[1] = Convert.ToDateTime("08/12/2020");
table2.Rows.Add(row);
row = table2.NewRow();
row[0] = "9";
row[1] = Convert.ToDateTime("02/25/2020");
table2.Rows.Add(row);
row = table3.NewRow();
row[0] = "1";
row[1] = Convert.ToDateTime("03/20/2020");
table3.Rows.Add(row);
row = table3.NewRow();
row[0] = "2";
row[1] = Convert.ToDateTime("01/11/2020");
table3.Rows.Add(row);
row = table3.NewRow();
row[0] = "12";
row[1] = Convert.ToDateTime("01/21/2020");
table3.Rows.Add(row);
row = table3.NewRow();
row[0] = "8";
row[1] = Convert.ToDateTime("09/22/2020");
table3.Rows.Add(row);
row = table3.NewRow();
row[0] = "11";
row[1] = Convert.ToDateTime("01/20/2020");
table3.Rows.Add(row);
var query = from t1 in table1.AsEnumerable()
join t2 in table2.AsEnumerable()
on t1.Field<string>("Id") equals t2.Field<string>("Id")
join t3 in table3.AsEnumerable()
on t1.Field<string>("Id") equals t3.Field<string>("Id")
select new
{
Id = t1.Field<string>("Id"),
LastModified = Max(t1.Field<DateTime>("Date"), t2.Field<DateTime>("Date"), t3.Field<DateTime>("Date"))
};
}
static DateTime Max(DateTime a, DateTime b, DateTime c)
{
//Get max value between three.
DateTime[] aa = { a, b, c };
return aa.Max();
}