C# 如何将数据获取为IEnumerable<;模型>;通过使用LINQ从DataTable?
我有一个C# 如何将数据获取为IEnumerable<;模型>;通过使用LINQ从DataTable?,c#,linq,datatable,C#,Linq,Datatable,我有一个DataTable,其中包含一些从数据库获取的属性数据,该DataTable中的每个数据都属于一个产品,每个产品可以有多个属性 因此,我有另一个DataTable,它在foreach中包含所有产品,通过循环遍历每一行,我将每个产品添加到它的列表中,如下所示: var productAttr = new List<Plu.Attributi>(); foreach (DataRow rowPlu in dt.Rows) { try { int i
DataTable
,其中包含一些从数据库获取的属性数据,该DataTable
中的每个数据都属于一个产品,每个产品可以有多个属性
因此,我有另一个DataTable
,它在foreach
中包含所有产品,通过循环遍历每一行,我将每个产品添加到它的列表中,如下所示:
var productAttr = new List<Plu.Attributi>();
foreach (DataRow rowPlu in dt.Rows)
{
try
{
int id = (int)rowPlu["ID_PLUREP"];
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;
}
}
然后我在foreach
foreach (DataRow rowPlu in dt.Rows)
{
try
{
int id = (int)rowPlu["ID_PLUREP"];
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"],
from row in attributi.AsEnumerable() where row.Field<int>("ID_PLUREP_VAT") == id select row,
null,
(int)rowPlu["ID_MENU_PRP"]
));
}
catch
{
return plu;
}
}
foreach(数据行中的行)
{
尝试
{
int id=(int)rowPlu[“id_PLUREP”];
plu.添加(新plu)(
身份证件
(字符串)rowPlu[“CODICE_PRP”],
(字符串)rowPlu[ESTESA],
(字符串)rowPlu[DESCR],(float)rowPlu[“PRE_PRP”],
rowPlu.IsNull(“IMG_IMG”)?null:(字符串)rowPlu[“IMG_IMG”],
从attributei.AsEnumerable()中的行,其中row.Field(“ID\u PLUREP\u VAT”)==ID选择行,
无效的
(int)rowPlu[“ID\U MENU\U PRP”]
));
}
接住
{
返回plu;
}
}
但是LINQ返回一个EnumerablerRowCollection
,而我需要一个IEnumerable
,所以我想知道是否有一种惰性方法可以将.AsEnumerable
转换为IEnumerable
。您可以执行如下操作。如果需要IEnumerable
,可以从末尾删除.ToList()
dt.AsEnumerable().Select(x => new Plu {
Id = x.Field<int>("ID_PLUREP"),
CodicePrep = x.Field<string>("CODICE_PRP"),
....
Attributes = attributi.AsEnumerable()
.Where(y => y.Field<int>("ID_PLUREP_VAT") == x.Field<int>("ID_PLUREP"))
.Select(z => new Attributi
{
....
}).ToList(),
....
}).ToList();
dt.AsEnumerable().选择(x=>new Plu{
Id=x.Field(“Id\u PLUREP”),
CodicePrep=x.字段(“CODICE_PRP”),
....
Attributes=attributei.AsEnumerable()
其中(y=>y.Field(“ID\u PLUREP\u VAT”)==x.Field(“ID\u PLUREP”))
.选择(z=>新属性i
{
....
}).ToList(),
....
}).ToList();
问题在于,DataTable只知道单元格中的值。它不知道这些值代表什么。它不知道第0列中的数字实际上是一个Id。它不知道第1列中的字符串是客户的姓名,第2列中的日期时间是客户的生日
如果将来要将此数据表(或类似数据表)的内容用于其他查询,则需要从DataRow转换为它们所代表的项
一旦获得了从DataRow到Plu的转换,就可以将DataTable转换为IEnumerable
,并对其执行其他LINQ处理
用法如下:
DataTable table = ...
var mySelectedData = table.AsEnumerable().ToPlus()
.Where(plu => ...)
.Select(plu => new {...})
.ToList();
您需要两个扩展方法:一个将数据行转换为Plu,另一个将数据行序列转换为Plu序列。看
如果需要,可以使用列的名称代替columnIndex
因此,通过只创建一个ToPlu
,以及一个将数据行序列转换为加号序列的单行方法,您已经用读取表的方法扩展了LINQ
为了安全起见,考虑创建一个将Plus序列转换为DATABATE的扩展方法。这样,表的布局就位于一个位置:
ToPlu(DataRow)
和ToDataRow(Plu)
。表布局的未来更改将更易于管理,DataTable的用户将只考虑加号序列。.Cast()
?
DataTable table = ...
var mySelectedData = table.AsEnumerable().ToPlus()
.Where(plu => ...)
.Select(plu => new {...})
.ToList();
public static Plu ToPlu(this DataRow row)
{
// TODO implement
}
public static IEnumerable<Plu> ToPlus(this IEnumerable<DataRow> dataRows)
{
// TODO: exception if null dataRows
return dataRows.Select(row => row.ToPlu());
}
public static IEnumerable<Plu> ExtractPlus(this DataTable table)
{
// TODO: exception if table null
return table.AsEnumerable().ToPlus();
}
DataTable table = ...
IEnumerable<Plu> plus = table.ExtractPlus();
class Customer
{
public int Id {get; set;} // Id will be in column 0
public string Name {get; set;} // Name will be in column 1
...
}
public static Customer ToCustomer(this DataRow row)
{
return new Customer
{
Id = (int)row[0],
Name = (string)row[1],
};
}