使用LINQ查询DataTable

时间:2011-05-14 09:59:58

标签: c# .net linq ado.net datatable

首先道歉,如果我没有正确解释这一点,我已经在这几个小时,现在是早上。

我尝试了很多方法,得到了很多错误,我记不起原始版本了,我也无法解决问题,这是我的代码,这很糟糕因为我应该使用连接查询我的SP被窃听在这台服务器上。

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”的查询模式的实现。 '哪里'找不到。

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

EDIT2:

我失败了,设法再次重新制造问题,感叹

 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);

2 个答案:

答案 0 :(得分:8)

dt.Rows.Add()接受DataRow,但您的提供IEnumerable<DataRow> 另请注意,行只能添加到使用DataTable创建的dt.NewRow()尝试使用dt.ImportRow()代替

修改

跳过临时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];
    }
}

答案 1 :(得分:0)

别忘了

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