Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将数据获取为IEnumerable<;模型>;通过使用LINQ从DataTable?_C#_Linq_Datatable - Fatal编程技术网

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],
    };
}