使用LINQ查询DataTable

5

首先,如果我没有解释清楚,对不起,我已经忙碌了几个小时,现在已经是早上了。

我尝试过很多方法,遇到了很多错误,我已经记不起原来的版本了,也无法解决问题,这是我的代码,它很糟糕,因为我应该使用连接查询,但我的存储过程在这个服务器上有 bug。

SqlConnection conn = new SqlConnection(connstring);
DataSet ds = new DataSet();
SqlDataAdapter ad;
SqlCommand cmd = new SqlCommand();
ad = new SqlDataAdapter("SELECT * FROM booking WHERE bookstartdate BETWEEN '" + ReturnDbDate(datefrom).ToString() + "' AND '" + ReturnDbDate(dateto).ToString() + "'", conn);
ad.Fill(ds, "CustomerIds");

ad = new SqlDataAdapter("SELECT customerid, firstname, lastname, telephone, email FROM customer", conn);
ad.Fill(ds, "Customers");

DataTable dt = new DataTable();
dt.Columns.Add("Customerid", typeof(String));
dt.Columns.Add("Firstname", typeof(String));
dt.Columns.Add("Lastname", typeof(String));
dt.Columns.Add("Telephone", typeof(String));
dt.Columns.Add("Email", typeof(String));

int lol = ds.Tables["CustomerIds"].Rows.Count;

foreach (DataRow row in ds.Tables["CustomerIds"].Rows)
{
    IEnumerable<DataRow> r = from dr in ds.Tables["Customers"].AsEnumerable()
                             where dr.Field<Guid>("customerid").ToString() == row[2].ToString()
                             select dr;
    dt.Rows.Add(r);
}

return dt;

当我尝试使用以下代码循环遍历数据集时:

foreach (DataRow rows in dt.Rows)
{
    sb.Append("<tr><td>" + rows["Customerid"].ToString() + "</td><td>" + rows[1] + "</td><td>" + rows[2] +"</td><td>" + rows[3] + "</td></tr>");
}

我得到了:

System.Data.EnumerableRowCollection`1[System.Data.DataRow]

有人有什么想法吗?我现在完全脑残了,所以这可能是一些简单的东西。
谢谢。
编辑:
DataRow r = from dr in ds.Tables["Customers"]
            where dr.Field<Guid>("customerid").ToString() == row[2].ToString()
            select dr;    
dt.ImportRow(r);

错误: 找不到' System.Data.DataTable '源类型的查询模式实现。未找到'Where'。

我假设我的LINQ语法是正确的,尽管我认为有一个IEnumberable<T>.Where()方法?我记得它,只是不记得如何访问它。

编辑2:

我失败了,又一次重现了这个问题,叹气。

 IEnumerable<DataRow> r = from dr in ds.Tables["Customers"].Select().Where(x => x.Field<Guid>("customerid").ToString() == row[2].ToString())
                            select dr;



                dt.ImportRow(r);

这是一个比较两个数据集表中的数据,并创建一个新的数据表并用上述条件数据填充的情况。 - Ash
2个回答

8

dt.Rows.Add()需要传入一个DataRow,但您提供的是IEnumerable<DataRow>。请注意,只能将行添加到使用dt.NewRow()创建的DataTable中,请尝试改用dt.ImportRow()

编辑:

跳过临时DataTable,而是在数据集中连接这两个DataTable。或者更好的方法是,跳过使用Linq,在数据库查询中连接这些表。

return 
  from dr in ds.Tables["Customers"].AsEnumerable()
  join dr2 in ds.Tables["CustomerIds"].AsEnumerable()
    on dr.Field<Guid>("customerid") equals dr2.Field<Guid>(2)
  select dr;

纯 SQL

public DataTable GetCustomers(DataTime datefrom, DataTime dateto)
{
    var sql = @"
        SELECT customer.customerid, firstname, lastname, telephone, email
        FROM customer
        JOIN booking
            ON customer.customerid = booking.customerid
        WHERE bookstartdate BETWEEN '" + ReturnDbDate(datefrom).ToString() + "' AND '" + ReturnDbDate(dateto).ToString() + "'";

    using (SqlConnection conn = new SqlConnection(connstring))
    using (SqlDataAdapter ad = new SqlDataAdapter(sql, conn))
    {
            DataSet ds = new DataSet();
            ad.Fill(ds);
            return ds.tables[0];
    }
}

干杯,我稍微改了一下我的代码,但仍然遇到了问题。 - Ash
我现在非常喜欢你,哈哈,没想到内联连接SQL语句是可能的。问题解决了。 - Ash

1

不要忘记

using System.Linq;

否则,您将无法使用LINQ扩展方法。

试试这个:

  • 添加对 System.Data.DataSetExtensions.dll 的引用
  • IEnumerable<DataRow> r = ds.Tables["Customers"].AsEnumerable();
  • 使用任何 LINQ 扩展方法:

    from r in ds.Tables["Customers"].AsEnumerable()
    where r.Field<Guid>("customerid") == row[2]
    select r;
    

你的 ADO.NET 代码可以改写成这样:

using (DataSet ds = new DataSet())
{
    using (SqlConnection conn = new SqlConnection(connstring))
    using (SqlDataAdapter ad = new SqlDataAdapter("", conn))
    {
        ad.Fill(ds);
    }

    // access ds;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接