我有一个由存储过程填充的DataTable,以及包含Requests(RequestNumber and Tasks(TaskId)
集合的数据表。当我通过任务到达第一个请求编号时,我将其添加到我的列表中,然后使用其他数据行,我检查列表以查看它们是否存在(if(dr["RequestNumber"].ToString() != acList[i].RequestNumber)
)如果有,我删除dataRow,如果不是我把它们添加到列表中。
这在顺序中很好用,但如果数据行和列表一个接一个,它就允许添加行。如果值存在于列表中,还有其他方法可以完成查找。
提前致谢。
foreach (DataRow dRow in dt.Rows)
{
DataRow dr = dt.NewRow();
dr["Project"] = dRow["Project"];
dr["RequestNumber"] = dRow["RequestNumber"];
dr["RequestId"] = dRow["RequestId"];
dr["TaskType"] = dRow["TaskType"];
dr["TaskId"] = dRow["TaskId"];
dr["TaskStatus"] = dRow["TaskStatus"];
dr["AssignedTo"] = dRow["AssignedTo"];
dr["DateDue"] = dRow["DateDue"];
if (acList.Count == 0)
{
acList.Add(new AssignedClass
{
Project = dr["Project"].ToString(),
RequestNumber = dr["RequestNumber"].ToString(),
RequestId = dr["RequestId"].ToString(),
TaskType = dr["TaskType"].ToString(),
TaskId = dr["TaskId"].ToString(),
TaskStatus = dr["TaskStatus"].ToString(),
AssignedTo = dr["AssignedTo"].ToString(),
DateDue = dr["DateDue"].ToString()
});
}
else
{
for (int i = 0; i < acList.Count; i++)
{
if(dr["RequestNumber"].ToString() != acList[i].RequestNumber)
{
acList.Add(new AssignedClass
{
Project = dr["Project"].ToString(),
RequestNumber = dr["RequestNumber"].ToString(),
RequestId = dr["RequestId"].ToString(),
TaskType = dr["TaskType"].ToString(),
TaskId = dr["TaskId"].ToString(),
TaskStatus = dr["TaskStatus"].ToString(),
AssignedTo = dr["AssignedTo"].ToString(),
DateDue = dr["DateDue"].ToString()
});
}
else
{
dr.Delete();
}
}
}
答案 0 :(得分:5)
使用LINQ,就像检查是否有匹配一样简单:
if ( !acList.Any(a => a.RequestNumber == dr["RequestNumber"].ToString() )
acList.Add( ... );
此外,似乎开头将dRow
分配给dr
的代码没有任何意义。只需在代码的其余部分直接使用dRow
即可。而且我认为您不希望将(acList.Count == 0)
视为一种特殊情况,因为这只会导致您必须复制逻辑,从而维护相同代码的两个单独副本。因此,如果我理解正确,这个简化的代码应该完成同样的事情:
foreach (DataRow dRow in dt.Rows)
{
if ( !acList.Any(a => a.RequestNumber == dRow["RequestNumber"].ToString() )
{
acList.Add(new AssignedClass
{
Project = dRow["Project"].ToString(),
RequestNumber = dRow["RequestNumber"].ToString(),
RequestId = dRow["RequestId"].ToString(),
TaskType = dRow["TaskType"].ToString(),
TaskId = dRow["TaskId"].ToString(),
TaskStatus = dRow["TaskStatus"].ToString(),
AssignedTo = dRow["AssignedTo"].ToString(),
DateDue = dRow["DateDue"].ToString()
});
}
}
答案 1 :(得分:2)
这对于LINQ的 Union
方法来说非常棒,但它需要IEqualityComparer<AssignedClass>
实现。除非你经常这样做,否则它可能不值得编码(即使它是10-ish线,如果正确完成)。不过,这会有所帮助:
acList = acList
.Concat(from row in dt.Rows
from ac in acList
where ac.RequestNumber != row["RequestNumber"].ToString()
select AssignedClassFromDataRow(row))
.ToList();
,其中
private static AssignedClass AssignedClassFromDataRow(DataRow row)
{
// maybe some checks...
return new AssignedClass
{
Project = dRow["Project"].ToString(),
RequestNumber = dRow["RequestNumber"].ToString(),
RequestId = dRow["RequestId"].ToString(),
TaskType = dRow["TaskType"].ToString(),
TaskId = dRow["TaskId"].ToString(),
TaskStatus = dRow["TaskStatus"].ToString(),
AssignedTo = dRow["AssignedTo"].ToString(),
DateDue = dRow["DateDue"].ToString()
}
}
比基于散列的解决方案稍微复杂一点,但很容易实现。
编辑:
如果您确实需要散列提供的额外性能,可以编写EqualityComparer(但请记住 these guidelines )。这样的解决方案最终看起来像这样:
acList = acList
.Union(
dt.Rows.Select(AssignedClassFromDataRow),
new MyAssignedClassRequestNumberComparer())
.ToList();
答案 2 :(得分:0)
您可以使用HashSet<AssignedClass>
,您只需要创建自定义IEqualityComarer<AssignedClass>
,在其中检查传递对象的RequestNumber
属性,并在{{1}的构造函数中传递此比较器的实例}}
修改强>
以下是HashSet
:
IEqualityComarer<AssignedClass>
<强> EDIT2:强> 或者你可以简单地使用HashSet来存储密钥,同时枚举行:
public class AssignedClassComparer : IEqualityComparer<AssignedClass>
{
public bool Equals(AssignedClass x, AssignedClass y)
{
return x.RequestNumber == y.RequestNumber;
}
public int GetHashCode(AssignedClass obj)
{
return obj.RequestNumber.GetHashCode();
}
}
答案 3 :(得分:0)
使用linq选项并考虑到开始代码块和检查0条目似乎有点多余。我认为这个过程可以归结为
var distinctRows = dt.Rows.GroupBy(x => x["RequestNumber"]).Select(x => x.First());
acList.AddRange(distinctRows.Select(x => x.MapToAssignedClass());
// Added Mapping method for readability
public static AssignedClass MapToAssignedClass(this DataRow dr)
{
return new AssignedClass
{
Project = dr["Project"].ToString(),
RequestNumber = dr["RequestNumber"].ToString(),
RequestId = dr["RequestId"].ToString(),
TaskType = dr["TaskType"].ToString(),
TaskId = dr["TaskId"].ToString(),
TaskStatus = dr["TaskStatus"].ToString(),
AssignedTo = dr["AssignedTo"].ToString(),
DateDue = dr["DateDue"].ToString()
});
}