使用 linq 联接两个表,并填写它们的字典
本文关键字:字典 两个 linq 使用 | 更新日期: 2023-09-27 18:19:59
我一直在搜索如何连接两个表(数据和数据值,一对多(并填写类型的字典。
数据的记录可能是数千条(例如 500,000 条或更多(,每个数据可能有 10 到 20 个 DataValues,这使得它成为一个更重的查询,因此性能在这里非常重要。
这是我编写的代码:
// Passed via the arguments, for example, sensorIDs would contain:
int[] sensorIDs = { 0, 1, 2, 3, 4, 5, 6, 17, 18 };
Dictionary<Data, List<DataValue>> dict = new Dictionary<Data, List<DataValue>>();
foreach (Data Data in dt.Datas)
{
var dValues = from d in dt.Datas
join dV in dt.DataValues on d.DataID equals dV.DataID
where (SensorIDs.Contains(dV.SensorID))
select dV;
dict.Add(Data, dValues.ToList<DataValue>());
}
但这种方法存在严重的性能问题,需要很长时间才能执行。不确定我是否需要使用 SQL 视图。有什么建议吗?
> 你查询的次数太多了。您可以在一个查询中执行此操作。
var dict = (from d in dt.Datas
join dV in dt.DataValues on d.DataID equals dv.DataID
where SensorIDs.Contains(dv.SensorID)
select new { d, dV }).ToDictionary(o => o.d, o => o.dV.ToList());
在你的foreach
循环中,你正在获取所有Data
,对于它们中的每一个,你都在做同样的事情。
编辑:现在这不是很清楚,但我认为您只想加入 SensorID 数组中的DataValue
。在这种情况下:
var dict = (from d in dt.Datas
let dV = (from dataValue in dt.DataValues
where SensorIDs.Contains(dataValue.SensorID) &&
dataValue.DataID = d.DataID
select dataValue)
select new { d, dV }).ToDictionary(o => o.d, o => o.dV.ToList());
在这种情况下,您不需要foreach
循环,您可以使用组联接直接从 linq 创建字典,这应该会为您提供更好的性能。
dict=(from DataValue d in dt.DataValues
where sensorIDs.Contains(d.SensorID)
group d by d.DataID
into datavalues
join data in dt.Datas
on datavalues.Key equals data.DataId
select new {
Key = data,
Value = datavalues
}).ToDictionary(a=>a.Key,a=>a.Value.ToList());
或者可以使用 LINQ 表达式方法
dict = dt.DataValues.Where(d=>sensorIDs.Contains(d.SensorID))
.GroupBy(a=>a.DataID)
.Join(dt.Datas,a=>a.Key,a=>a.DataId,
(a,b)=>new{Key=b,Value=a.ToList()})
.ToDictionary(a=>a.Key,a=>a.Value);
你不需要 foreach 循环。通常尝试这样的事情:
var columns = dt.Columns.Cast<DataColumn>();
dt.AsEnumerable().Select(dataRow => columns.Select(column =>
new { Column = column.ColumnName, Value = dataRow[column] })
.ToDictionary(data => data.Column, data => data.Value));
另外,请考虑阅读以下内容:http://blogs.teamb.com/craigstuntz/2010/01/13/38525/