如何通过LINQ将DataTable转换为IEnumerable<Plu.Attribute>?
把筛选后的DataRow集合转换成IEnumerable<Plu.Attributi>的简便方法
你现在遇到的问题很明确:LINQ筛选出来的是EnumerableRowCollection<DataRow>,但Plu的构造函数需要的是IEnumerable<Plu.Attributi>。解决思路其实很简单——在LINQ查询里多一步映射转换,把每个DataRow转换成Plu.Attributi实例就行。
直接在LINQ里完成转换
你可以在Where筛选之后,用Select方法把符合条件的每一行数据映射成Plu.Attributi对象。具体代码修改如下:
foreach (DataRow rowPlu in dt.Rows) { try { int id = (int)rowPlu["ID_PLUREP"]; // 先筛选匹配ID的属性行,再转换成Plu.Attributi集合 var productAttr = attributi.AsEnumerable() .Where(row => row.Field<int>("ID_PLUREP_VAT") == id) .Select(row => new Plu.Attributi( // 这里替换成你Plu.Attributi构造函数需要的参数,比如: row.Field<int>("ID_ATTRIBUTE"), // 假设属性表有ID字段 row.Field<string>("ATTR_NAME"), // 属性名称 row.Field<string>("ATTR_VALUE") // 属性值 // 其他字段根据你的类定义补充完整 )); plu.Add(new Plu( id, (string)rowPlu["CODICE_PRP"], (string)rowPlu[ESTESA], (string)rowPlu[DESCR], (float)rowPlu["PRE_PRP"], rowPlu.IsNull("IMG_IMG") ? null : (string)rowPlu["IMG_IMG"], productAttr, null, (int)rowPlu["ID_MENU_PRP"] )); } catch { return plu; } }
如果Plu.Attributi支持无参构造函数,也可以用对象初始化器来赋值,写法更灵活:
.Select(row => new Plu.Attributi { Id = row.Field<int>("ID_ATTRIBUTE"), Name = row.Field<string>("ATTR_NAME"), Value = row.Field<string>("ATTR_VALUE") })
优化性能:提前构建属性字典
如果你的属性数据量比较大,每次循环都遍历整个attributi表会有点浪费性能。建议在循环外面先把属性数据按ID_PLUREP_VAT分组,转成字典,这样每次查找只需要O(1)的时间:
// 循环外提前构建字典:键是产品ID,值是对应属性集合 var attributeDict = attributi.AsEnumerable() .GroupBy(row => row.Field<int>("ID_PLUREP_VAT")) .ToDictionary( group => group.Key, group => group.Select(row => new Plu.Attributi( // 同样替换成你的构造参数 row.Field<int>("ID_ATTRIBUTE"), row.Field<string>("ATTR_NAME"), row.Field<string>("ATTR_VALUE") )) ); // 循环内直接从字典取属性 foreach (DataRow rowPlu in dt.Rows) { try { int id = (int)rowPlu["ID_PLUREP"]; // 尝试获取对应属性,没有的话返回空集合 attributeDict.TryGetValue(id, out var productAttr); plu.Add(new Plu( id, (string)rowPlu["CODICE_PRP"], (string)rowPlu[ESTESA], (string)rowPlu[DESCR], (float)rowPlu["PRE_PRP"], rowPlu.IsNull("IMG_IMG") ? null : (string)rowPlu["IMG_IMG"], productAttr ?? Enumerable.Empty<Plu.Attributi>(), null, (int)rowPlu["ID_MENU_PRP"] )); } catch { return plu; } }
这样修改后,既解决了类型转换的问题,还能提升代码的执行效率,一举两得~
内容的提问来源于stack exchange,提问作者Kasper Juner
相关产品推荐
相关产品推荐

