【问题标题】:filter a data table with values from an array c#使用数组c#中的值过滤数据表
【发布时间】:2014-01-23 13:19:50
【问题描述】:

我有一个删除方法,它获取一组 GUID,我有一个数据表...如何过滤数据表,使其只包含这些 GUID?

public void delete(Guid[] guidlist)
{
datatable template = ReadTemplateList()
...
}

谢谢!

【问题讨论】:

  • 您是否愿意创建没有过滤行的DataTable 的副本?

标签: c# arrays select filter datatable


【解决方案1】:

使用 Linq to DataSet,您可以创建新的 DataTable,其中只有带有这些 Guid 的行:

public void Delete(Guid[] guids)
{
   DataTable table = ReadTemplateList()
                         .AsEnumerable()
                         .Where(r => guids.Contains(r.Field<Guid>("ColumnName")))
                         .CopyToDataTable();

   // ...
}

另一个选项(也适用于旧的 .NET 版本)是使用支持 IN 过滤器的内置 RowFilter 功能过滤您的表。假设您正在按名为 ID 的列进行过滤:

// Check if guids.Length > 0
StringBuilder filter = new StringBuilder("ID IN ("); 
foreach (Guid id in guids)
    filter.AppendFormat("Convert('{0}','System.Guid'),", id);
filter.Append(")");

DataTable template = ReadTemplateList();
DataView view = template.DefaultView;
view.RowFilter = filter.ToString();
DataTable table = view.ToTable();

【讨论】:

  • 我没有 Contains 方法,只有 CompareTo、Equals、GetHashCode、GetType、ToByteArray、ToString
  • @Andrew 只需添加 using System.Linq; 命名空间 - 这是扩展方法,在那里声明
  • 现在我收到一条错误消息“无法将类型“数据表”隐式转换为类型“templates_viewDataTable”。存在显式转换(您是否缺少演员表?)”
  • @Andrew 你在使用类型化数据表吗?
【解决方案2】:

您可以使用 LINQ:

public static DataTable DeleteGuidsFromTemplate(Guid[] guidlist)
{
    DataTable template = ReadTemplateList();
    var rowsWithGuids = from row in template.AsEnumerable()
                        join guid in guidlist 
                        on row.Field<Guid>("Guid") equals guid
                        select row;
    return rowsWithGuids.CopyToDataTable();
}

如果您因为低于 NET 3.5 而无法使用 LINQ:

public static DataTable DeleteGuidsFromTemplate(Guid[] guidlist)
{
    DataTable template = ReadTemplateList();
    DataTable templateGuids = template.Clone();
    foreach(DataRow row in template.Rows)
    { 
        Guid guid = (Guid)row["Guid"];
        int index = Array.IndexOf(guidlist, guid);
        if (index >= 0)
            templateGuids.ImportRow(row);
    }
    return templateGuids;
}

【讨论】:

    【解决方案3】:

    基于DataTableDataRows的解决方案。

            //fill the datatable from back end
            string connStr = ConfigurationManager.ConnectionStrings["ConsoleApplication1.Properties.Settings.NORTHWNDConnectionString"].ConnectionString;            
            SqlConnection conn = new SqlConnection(connStr);
            conn.Open();
            SqlCommand comm = new SqlCommand("select categoryid,categoryname from Categories order by categoryname");            
            comm.Connection = conn;
            SqlDataReader dr = comm.ExecuteReader();
            DataTable dt = new DataTable();           
            dt.Load(dr);
    
            //datatable filter logic
            string[] filter = { "1", "2" };
    
    
            DataTable filteredTable =   dt.Clone();
            foreach (string str in filter)
            {
                DataRow[] filteredRows = dt.Select("categoryid="+ str); //search for categoryID
                foreach (DataRow dtr in filteredRows)
                {
                    filteredTable.ImportRow(dtr);
                }                
    
            }
    

    编辑

    不用去for loop

    DataTable dt = new DataTable();           
    dt.Load(dr);    //fill the datatable with sqldatareader        
    DataTable filteredTable =   dt.Clone();
    DataView dv = dt.DefaultView;            
    dv.RowFilter = "categoryid in (1,2)";
    filteredTable = dv.ToTable();
    

    【讨论】:

      猜你喜欢
      • 2017-07-20
      • 2018-10-02
      • 2015-11-20
      • 1970-01-01
      • 2023-03-28
      • 2017-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多