【问题标题】:Linq Excluding a columnLinq 排除列
【发布时间】:2015-12-24 15:12:40
【问题描述】:

全部—— 我在尝试从 Linq 查询中排除列时遇到了一个小问题。我要做的是找到除 ID 列之外的至少一列具有数据的所有行。 ID 列设置为自动增量,因此它将始终包含数据。通常,数据表是从其他一些数据存储(即 Excel、Access、CSV 等)加载的,有时其中一些行不包含数据。我目前的工作是从数据表 (dt1) 中删除该 ID 列,然后将其添加回数据表并重新填充该列。 注意:列的总数可以从 10 到 100 不等,因此任何解决方案都必须是动态的。

在下面的示例中,只有第 1 行到第 4 行包含所有列中的数据,其中第 0 行和第 5 行仅包含 ID 列中的数据。在 dt2 中,我只希望添加第 1 到第 4 行。所以我的问题是我将如何从下面的 LINQ 查询中删除 ID 列?

提前感谢任何建设性的建议!

private void LoadDataTable()
{
        DataTable dt1 = new DataTable();

        //Create three columns
            DataColumn dc = new DataColumn("ID", typeof(Int32));
            dc.AutoIncrement = true;
            dc.AllowDBNull = false;
            dc.AutoIncrementSeed = 1;
            dt1.Columns.Add(dc);
            dc.SetOrdinal(0);

            dc = new DataColumn("Item", typeof(String));
            dt1.Columns.Add(dc);

            dc = new DataColumn("Quantity", typeof(Int32));
            dt1.Columns.Add(dc);

        //Create items Array
            string[] items = new string[] { "Ford", "Chevy", "GMC", "Buick", "Toyota", "Honda", "Mercury"
                                                ,"Hyundai", "Rolls Royce", "BMW", "Mercedes Benz", "Bentley", "Porche"
                                                ,"Infinity", "Jaguar" };

        //Load Dummy data
            Random rnd = new Random();
            for (int i = 0; i < 5; i++)
            {
                DataRow dr = dt1.NewRow();

                if (i > 0 && i < 4)
                {
                    dr[1] = items[rnd.Next(i, items.Count())];
                    dr[2] = rnd.Next(i, 10000);

                    //Remove previously used Item from Array
                        items = items.Where(w => w != dr[1].ToString()).ToArray(); 
                }
                dt1.Rows.Add(dr);
            }

        //dt2 should only contain rows who have data in at least one column with the exception of the ID Column
            DataTable dt2 = dt1.Rows.Cast<DataRow>()
                            .Where(w => w.ItemArray.Any(field => !string.IsNullOrEmpty(field.ToString().Trim()) && !(field is DBNull)))
                            .CopyToDataTable();
}

更新

感谢 Ivan Stoev,这是解决方法

    //dt2 should only contain rows who have data in at least one column with the exception of the ID Column
    var columns = dt1.Columns.Cast<DataColumn>().Where(c => c.ColumnName != "ID").ToList();

    DataTable dt2 = dt1.Rows.Cast<DataRow>()
                    .Where(w => columns.Select(c => w[c]).Any(field => !string.IsNullOrEmpty(field.ToString().Trim()) && !(field is DBNull)))
                    .CopyToDataTable();

【问题讨论】:

  • 与您的问题无关,但如果您想要更多随机数,您应该在for 循环之外创建Random rnd,否则您将使用大致相同的种子值。这也将加快您的进程,因为您只需初始化一个新的Random 一次,这确实有一些开销。 MSDN
  • 是的,我通常只是快速将这个示例放在一起,谢谢!

标签: c# linq datatable


【解决方案1】:

您需要将查询中的ItemArray 替换为其他DataRow 值访问方法,例如这样

var columns = dt1.Columns.Cast<DataColumn>().Where(c => c.ColumnName != "ID").ToList();
DataTable dt2 = dt1.Rows.Cast<DataRow>()
    .Where(r => columns.Select(c => r[c]).Any(field => ... 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-20
    • 2010-10-11
    相关资源
    最近更新 更多