C# 用linq替换foreach

C# 用linq替换foreach,c#,linq,C#,Linq,我有一个objectEPSElement的列表。在EPSElement中有一个字段ColumnValue,它从数据表dt=ds.Tables[1];获取数据;。为了实现这一点,我正在使用there foreach循环。是否有更好的方法来实现这一点。我不太喜欢每个循环三次。这可以用LINQ代替吗?我永远不会尝试用LINQ代替它。首先,你在foreach的体内变异,这是一个坏主意,试图用LINQ做。LINQ是关于查询LINQ中的“Q”,LINQ是用于查询的,因此不应该有副作用。但是,即使假设你要用一

我有一个objectEPSElement的列表。在EPSElement中有一个字段ColumnValue,它从数据表dt=ds.Tables[1];获取数据;。为了实现这一点,我正在使用there foreach循环。是否有更好的方法来实现这一点。我不太喜欢每个循环三次。这可以用LINQ代替吗?

我永远不会尝试用LINQ代替它。首先,你在foreach的体内变异,这是一个坏主意,试图用LINQ做。LINQ是关于查询LINQ中的“Q”,LINQ是用于查询的,因此不应该有副作用。但是,即使假设你要用一个新的物体序列的投影来代替突变,把它转换成LINQ也是很难理解的;嵌套逻辑太多。别管它。

这可以很好地解释。每个foreach es都转换为它们自己的from,少数变量是每个let,所有的if最终都是where's


然后,实现可以是我的查询中的逻辑,也可以是您喜欢的原始代码中的逻辑。

看起来您正在重复使用每行的数据替换element.ColumnValue的值,这是有意的吗?非常感谢Jason,我将此代码保留了一段时间,但由于某种原因,有三个foreach让我感到不舒服。因为我一直在寻找的验证就是把它作为一个好主意,现在我可以毫无疑问地继续我的编码+1,除了副作用,我想如果我在linq看到它,我会失去生存的意愿…@Neha,如果您真的想清理外观,请将最内部的foreach循环移动到它自己的名为void ProcessRowEPSFromElement元素DataRow的函数。突出显示该块并单击rt->Refactor->Extract方法应该能够足够轻松地完成它。如果我有超深的巢穴,我会自己做这件事,让它更容易阅读。但是OP中的代码可以很容易地翻译成查询。在整个过程中,他只做了一件事,他对一组经过过滤的给定数据做了这件事。除了实际操作之外,其他一切都可以相当容易地转换为查询。@Servy:我没说不能。我不认为LINQ查询比OP已经拥有的过程代码更清晰、更容易维护。这是否更清晰、更易于维护等值得商榷。@Jason当然值得商榷,但通过向他展示如何使用LINQ实现这一点,他现在能够比较两者,并且能够判断他是否愿意这样做。如果您还没有看到我的编辑,我肯定会将该检查重构为它自己的方法。@Servy:还值得一提的是,您还可以简化select to select new{Element,ColumnData}也就是说,如果elementList中的第一行同样更改为from Element,则显式声明是不必要的。这是否更好是个人的喜好,但我认为这有助于让事情变得更清楚。@AndrewCoonce主要区别在于我个人想要一个不同的命名约定;anon对象属性使用pascal case,循环变量使用camal case。决定不做你所描述的是故意的。谢谢大家。我真的很感谢你们给我两个选择,我可以选择和实施
dt = ds.Tables[1];

foreach (EPSFromElement element in elementList)
{
    foreach (DataRow row in dt.Rows)
    {
        foreach (DataColumn column in dt.Columns)
            {
                var ColumnName = column.ColumnName;
                var ColumnData = row[column].ToString();
                var currentElement = Regex.Replace(element.Field_Label, @"\W", "");

                if (element.Module_Field_ID != null)
                {

                    if (currentElement == ColumnName)
                        element.ColumnValue = ColumnData;                                
                }
                else
                {
                    if (element.Field_Type_Name != "Checkbox")
                    {
                        if ("Q_" + element.Column_Name_ID == ColumnName)
                            element.ColumnValue = ColumnData;
                    }
                    else
                    {
                        if ("Q_" + element.Column_Name_ID + "_" + element.Value_Column_Name_ID == ColumnName)
                                    element.ColumnValue = ColumnData; 
                     }
                 }
        }
    }
}
var query = from element in elementList
            from row in dt.Rows.Cast<DataRow>()
            from column in dt.Columns.Cast<DataColumn>()
            let ColumnName = column.ColumnName
            let ColumnData = row[column].ToString()
            let currentElement = Regex.Replace(element.Field_Label, @"\W", "")
            where (element.Module_Field_ID != null && currentElement == ColumnName)
            || (element.Field_Type_Name != "Checkbox" 
                    && "Q_" + element.Column_Name_ID == ColumnName
                || element.Field_Type_Name == "Checkbox"
                    && "Q_" + element.Column_Name_ID + "_" + element.Value_Column_Name_ID == ColumnName)
            select new { Element = element, ColumnData = ColumnData };

foreach (var item in query)
    item.Element.ColumnValue = item.ColumnData;
where IsValid(element, ColumnName, currentElement)