C# 在linq中查找缺少的datacolum列名和行号
我有一个数据表,大约有50-60列 我有一个这样的列表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
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());