使用C#在LINQ中查询DataTable

时间:2014-05-09 10:04:01

标签: c# linq

我想使用LINQ在内存数据表中查询并在DataGridView上查看结果

有些时候我想重用这段代码(LINQ),然后我不能将列名硬编码为。因为有些时候列大小可能不同,所以我想为每个搜索条件逐一编写LINQ码。

var filter = (from myrow in rsTable.AsEnumerable()
             orderby myrow[0]
             where myrow.Field<string>(0).ToLower().Contains(search) || myrow.Field<string>(1).ToLower().Contains(search)
             select myrow).ToList().CopyToDataTable();

如果有一种方法可以将参数作为列名称或任何方法传递,以将此部分作为函数或该部件的任何解决方案进行改进?

示例代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SampleLambdaExp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            dataGridView1.DataSource = GetDataTable();
        }
        private DataTable GetDataTable() {
            string str = Properties.Settings.Default.Setting;
            SqlConnection con = new SqlConnection();
            con.ConnectionString = str;
            string query = "SELECT [Description] ,[Type] ,[Category] FROM [AdventureWorks2008R2].[Sales].[SpecialOffer]";
            con.Open();
            SqlCommand com = new SqlCommand(query,con);
            SqlDataAdapter da = new SqlDataAdapter(com);
            DataSet ds = new DataSet();
            da.Fill(ds);
            return ds.Tables[0];

        }
        private void DetailsFilter(string search)
        { 
            dataGridView1.DataSource = null;
            DataTable rsTable = null;
            rsTable = GetDataTable();
            try
            {
                var filter = (from myrow in rsTable.AsEnumerable()
                              orderby myrow[0]
                              where myrow.Field<string>(0).ToLower().Contains(search) || myrow.Field<string>(1).ToLower().Contains(search)
                              select myrow).ToList().CopyToDataTable();

                if (filter.Rows.Count > 0)
                {
                    dataGridView1.DataSource = filter;
                    dataGridView1.Columns[0].Visible = false;
                }
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (textBox1.Text == "" || textBox1.Text == String.Empty) { dataGridView1.DataSource = GetDataTable(); }
            else
            {
                DetailsFilter(textBox1.Text.ToLower());
            }
        }
    }
}

这是Windows窗体

enter image description here

1 个答案:

答案 0 :(得分:1)

最简单的方法是停止使用LINQ查询DataTable并开始使用DataView(并设置其RowFilter property)。

然后只需将DataView绑定到您的DataGridView即可。这也有一个好处,即每当过滤条件发生变化时,您都不需要创建一个全新的DataTable

所以你的代码看起来像:

public partial class Form1 : Form
{
   readonly DataTable _data;

   public Form1()
   {
       InitializeComponent();
       // querying a database in a ctor is bad IMHO, but that's just example code
       // keep a reference to the data once loaded
       _data = GetDataTable();
       // bind the gridview to the default DataView instead of the DataTable
       dataGridView1.DataSource = _data.DefaultView;
   }

   private DataTable GetDataTable() {
        ...
   }

   private void DetailsFilter(string search, IEnumerable<string> columnNames)
   { 
       // create the filter with AND and LIKE
       var filterString = String.Join(" AND ", columnNames.Select(c => String.Format("{0} LIKE '%{1}%'", c, search)));
       _data.DefaultView.RowFilter = filterString;
       // since the grid is bound the DataView, you immediately see the result
   }

   private void button1_Click(object sender, EventArgs e)
   {
       if (textBox1.Text == "" || textBox1.Text == String.Empty) 
       { 
           _data.DefaultView.RowFilter = String.Emtpy;
       }
       else
       {
           // note how we can pass column names
           DetailsFilter(textBox1.Text.ToLower(), new []{"Description", "Category"});
       }
   }
}

请注意它的缩短程度,避免多次查询数据库。

至于排序,只需Sort property