在Linq查询中调用函数

时间:2010-12-13 19:18:40

标签: linq

如果我想迭代一个集合,并在集合中的每个元素上调用一个函数,我可以选择:

foreach (var obj in objColl)
{
    MyFunction(obj);
}

如果我想用linq做这个,我可以使用其中任何一个:

//#1
var unused = (from var obj in objColl select MyFunction(obj)).ToList();

//#2
var unused = objColl.Select(obj => MyFunction(obj)).ToList();

我知道这有效,但似乎不对。当然,我的实际案例是更复杂的查询,但由于我可以使用Linq构建我的IQueryable并迭代它并调用函数,因此归结为此。

编辑: 这是我所做的一个例子。 (项目#是我无法透露的事情)

var dummyValue = (from
                  Item7 in dal.GetAgencyConvertions().Where(age => age.SourceName == "Item1" && age.TargetName == "Item2")
                  join Item6 in dal.GetAgencyConvertions().Where(age => age.SourceName == "Item2" && age.TargetName == "Item3") on Item6.TargetValue equals Item7.SourceValue
                  join agency in dal.GetAgencies() on Item7.SourceValue equals agency.Agency
                  orderby Item7.TargetValue
                  select vl.ValueListItems.Add(agency.ID, Item7.TargetValue)).ToList();

3 个答案:

答案 0 :(得分:5)

使用简单的foreach,因为您显然希望对集合中的对象执行操作(和/或使用),而不是希望项目/过滤器/组/等。序列中的项目。 LINQ是关于后一组操作的。

编辑:如果是您的更新,我只需创建一个查询,然后在foreach中迭代查询以执行操作。

var query = from Item7 in dal.GetAgencyConvertions().Where(age => age.SourceName == "Item1" && age.TargetName == "Item2") 
            join Item6 in dal.GetAgencyConvertions().Where(age => age.SourceName == "Item2" && age.TargetName == "Item3") on Item6.TargetValue equals Item7.SourceValue  
            join agency in dal.GetAgencies() on Item7.SourceValue equals agency.Agency 
            orderby Item7.TargetValue 
            select new { ID = agency.ID, Value = Item7.TargetValue };

foreach (var item in query)
    vl.ValueListItems.Add(item.ID, item.Value);

坦率地说,你的代码中发生了相同的循环,你只需使用ToList()扩展方法来掩盖它。作为副产品,您正在创建一个您无意使用的值列表,同时有点模糊代码的真实意图,所有这些都可以保存几个字符。

答案 1 :(得分:1)

通常情况下,查询不应该有任何副作用(即它不应该修改应用程序中数据或其他数据的状态)这引发了一个问题,会{ {1}}修改应用程序的状态?如果是,则应使用MyFunction循环。

答案 2 :(得分:1)

每个()扩展方法怎么样?

public static void Each<T>(this IEnumerable<T> target, Action<T> action)
{
    if (target == null) return;
    foreach (T obj in target)
        action(obj);
}