C# 在linq中查找缺少的datacolum列名和行号

C# 在linq中查找缺少的datacolum列名和行号,c#,linq,C#,Linq,我有一个数据表,大约有50-60列 我有一个这样的列表 public List<string> strImportRequiredFields = new List<string> { "ENTRY/CMD #", "PART #", "REFERENCE 1", "REFERENCE 2", "REFERENCE 3", "DUTY PER" }; public List strImportRequiredFields=新列表{“ENTRY/CMD#”、“PART

我有一个数据表,大约有50-60列

我有一个这样的列表

  public List<string> strImportRequiredFields = new List<string> { "ENTRY/CMD #", "PART #", "REFERENCE 1", "REFERENCE 2", "REFERENCE 3", "DUTY PER" };
public List strImportRequiredFields=新列表{“ENTRY/CMD#”、“PART#”、“REFERENCE 1”、“REFERENCE 2”、“REFERENCE 3”、“DUTY PER”};
这些是Datatable中必须包含的列,其值不应为空

如果该值为空,它将返回我的行号和列名,如果可能,用分隔符分隔

我已经浏览了很多链接,并以这个查询结束

List<DataRow> dtlist = dtUploadedDat.AsEnumerable().ToList();

            var result = dtlist.Where(p => strImportRequiredFields.Any(t => p[t].ToString().Length <= 0)).ToList();

            string rstring = string.Join(",", result.Select(x => x.ToString()).ToArray());
List dtlist=dtUploadedDat.AsEnumerable().ToList();
var result=dtlist.Where(p=>strImportRequiredFields.Any(t=>p[t].ToString().Length x.ToString()).ToArray());
它只给我计数值,我尝试了不同的条件,但没有得到排序

由于表可能包含1000条1000条记录中的1000条,因此如果我必须运行循环来检查它,这将是非常糟糕的

我想和林克一起完成

请帮忙


谢谢你做了一些小小的优化

List<DataRow> dtlist = dtUploadedDat.AsEnumerable();

var result = dtlist.Where(p => strImportRequiredFields.All(t => !string.IsNullOrEmpty(p[t].ToString()))); //check that all mandatory field not blank

string rstring = string.Join(",", result);
试试这个:

var result = dtUploadedDat.AsEnumerable()
             .SelectMany((row,i)=>dtUploadedDat.Columns.Cast<DataColumn>()
                  .Where(col=>!strImportRequiredFields.Contains(col.ColumnName)||
                               Convert.ToString(row[col]) == string.Empty)
                  .Select(col=>string.Format("{0},{1}",i+1,col.ColumnName)))
             .ToList();

//sample result
//{"ColumnA,1", "ColumnD,5", "ColumnF,8" } 
var result=dtUploadedDat.AsEnumerable()
.SelectMany((行,i)=>dtUploadedDat.Columns.Cast()
.Where(col=>!strImportRequiredFields.Contains(col.ColumnName)||
Convert.ToString(行[col])==string.Empty)
.Select(col=>string.Format(“{0},{1}”,i+1,col.ColumnName)))
.ToList();
//样本结果
//{“ColumnA,1”,“ColumnD,5”,“ColumnF,8”}

结果中的每一项都是一对列名和行索引(用逗号分隔)。

我创建了一个示例,您可以查看此示例

    private void Vaidate_Click(object sender, EventArgs e)
    {
        DataTable dt = new DataTable();
        dt.Columns.Add("ENTRY/CMD #", typeof(int));
        dt.Columns.Add("REFERENCE 1", typeof(string));
        dt.Columns.Add("REFERENCE 3", typeof(string));
        DataRow dr;
        for (int i = 0; i < 20; i++)
        {
            dr = dt.NewRow();
            dr[0] = i;
            dr[1] = "This" + i.ToString();
            dr[2] = "This" + i.ToString();
            dt.Rows.Add(dr);
        }

        dt.Rows[5][2] = "";
        dt.Rows[8][1] = "";
        //int itemFind = 157;
        //int rowindex = dt.Rows.IndexOf(dt.Select("Id=" + itemFind).FirstOrDefault());

        //List<string> strImportRequiredFields = new List<string> { "ENTRY/CMD #", "PART #", "REFERENCE 1", "REFERENCE 2", "REFERENCE 3", "DUTY PER" };
        List<string> strImportRequiredFields = new List<string> { "ENTRY/CMD #", "REFERENCE 1", "REFERENCE 3", };
        List<string> columnsPresent = dt.Columns.Cast<DataColumn>().Select(a => a.ColumnName).ToList();
        List<string> columnsNotPresent = strImportRequiredFields.Except(columnsPresent).ToList();

        if (columnsNotPresent != null && columnsNotPresent.Count > 0)
        {
            MessageBox.Show("Columns must present" + Environment.NewLine + columnsNotPresent.Aggregate((a, b) => a + "," + b));
            return;
        }


        string s = strImportRequiredFields.Aggregate((acc, next) => acc + next + " is Null or");

        var result = dt.AsEnumerable().Where(p => strImportRequiredFields.Any(t => string.IsNullOrEmpty(p[t].ToString())));

        List<int> Invalidrows = new List<int>();

        foreach (DataRow item in result)
        {
            Invalidrows.Add(dt.Rows.IndexOf(item));
        }

        if (Invalidrows != null && Invalidrows.Count > 0)
        {
            MessageBox.Show("some of field data missing in below rows" + Environment.NewLine + Invalidrows.Aggregate(
                        new StringBuilder(),
                        (sb, x) => sb.AppendLine(x.ToString())
                    ));

            return;
        }
    }
private void Vaidate\u单击(对象发送者,事件参数e)
{
DataTable dt=新的DataTable();
添加(“ENTRY/CMD#”,typeof(int));
添加(“参考1”,类型(字符串));
添加(“参考3”,类型(字符串));
数据行dr;
对于(int i=0;i<20;i++)
{
dr=dt.NewRow();
dr[0]=i;
dr[1]=“This”+i.ToString();
dr[2]=“This”+i.ToString();
dt.Rows.Add(dr);
}
dt.行[5][2]=“”;
dt.行[8][1]=“”;
//int itemFind=157;
//int rowindex=dt.Rows.IndexOf(dt.Select(“Id=”+itemFind).FirstOrDefault());
//List strImportRequiredFields=新列表{“ENTRY/CMD#“,“PART#“,“REFERENCE 1”,“REFERENCE 2”,“REFERENCE 3”,“DUTY PER”};
List strImportRequiredFields=新列表{“ENTRY/CMD#“,“REFERENCE 1”,“REFERENCE 3”,};
List columnsPresent=dt.Columns.Cast().Select(a=>a.ColumnName.ToList();
List columnsNotPresent=strImportRequiredFields.Except(columnsPresent.ToList();
if(columnsontpresent!=null&&columnsontpresent.Count>0)
{
MessageBox.Show(“列必须显示”+Environment.NewLine+columnsontpresent.Aggregate((a,b)=>a+”,“+b));
返回;
}
字符串s=strImportRequiredFields.Aggregate((acc,next)=>acc+next+“为空或“);
var result=dt.AsEnumerable().Where(p=>strImportRequiredFields.Any(t=>string.IsNullOrEmpty(p[t].ToString());
List Invalidrows=新列表();
foreach(结果中的数据行项目)
{
Invalidrows.Add(dt.Rows.IndexOf(item));
}
if(Invalidrows!=null&&Invalidrows.Count>0)
{
MessageBox.Show(“以下行中缺少一些字段数据”+Environment.NewLine+Invalidrows.Aggregate(
新建StringBuilder(),
(sb,x)=>sb.AppendLine(x.ToString())
));
返回;
}
}
试试这个

        StringBuilder sb = new StringBuilder();

        dt.AsEnumerable().Select((value, key) => new { value, key }).ToList()
            .ForEach(r => strImportRequiredFields.ForEach(c => { if (r.value[c].ToString().Length <= 0) sb.AppendFormat("\"row:{0},col:{1}\"", r.key, c); }));

        Console.WriteLine(sb.ToString());
StringBuilder sb=新建StringBuilder();
dt.AsEnumerable().Select((value,key)=>new{value,key}).ToList()

.ForEach(r=>strImportRequiredFields.ForEach(c=>{if(r.value[c].ToString()).Length您能提供少量示例输入和输出您想要的内容吗?@Grundy还需要什么,我已经给出了必填字段列表,datatable将有大约50-60个字段,其中这些字段不应为空,但在您的条件下,您测试至少有一个字段不为空,而不是为空all@Grundy我对linq非常陌生,我尝试了链接我从应答器中获取了try代码,但它将返回我的列名和行number@MAkela我只是不明白需要什么:-)col.name显示错误,我把它改为column name,但找不到row.indexit会返回字符串吗value@MAkela是的,这就是我所说的,每个条目都是一个字符串,正如我在示例结果中显示的(3个条目)。您想要什么类型的数据类型?是否有任何类来存储信息?或者您喜欢具有两个属性(一个是列名,另一个是行索引)的匿名类型?您说的是col=>!strImportRequiredFields.Contains(col.ColumnName)根据我得到的,它签入strimportrequiredfields,它会反转吗?当我运行代码时,我得到了liek@MAkela你的意思是什么?请在更新的问题中显示结果,显示你得到的任何异常,并进一步澄清你想要的实际数据类型。
        StringBuilder sb = new StringBuilder();

        dt.AsEnumerable().Select((value, key) => new { value, key }).ToList()
            .ForEach(r => strImportRequiredFields.ForEach(c => { if (r.value[c].ToString().Length <= 0) sb.AppendFormat("\"row:{0},col:{1}\"", r.key, c); }));

        Console.WriteLine(sb.ToString());