使用lambda表达式

时间:2015-05-06 09:44:51

标签: c# asp.net-mvc lambda

我试图在lambda表达式中调用一个控制器动作方法,如下所示。

此处dtImporteddataDataTable

public class DepartmentController : Controller
{
      public ActionResult Create(FormCollection collection, int ParentDepartmentID)
    {
       return view();
    }
}


   dtImporteddata.Rows.Cast<DataRow>().Select(r => new DepartmentController().Create(new FormCollection{ 
                {"ParentDepartmentID","57"},
                {"DepartmentPrefix",r["Prefix"].ToString()},
                {"DepartmentID","0"},
                {"IsSpecialDepartment",null},
                {"Description",r["Description"].ToString()},
                {"Name",r["Name"].ToString()},
                {"LocationIDs.$.PackedValue","4;;;"}
             }, 0)).ToList();

如果我像上面那样写,Create()方法被完美调用,但是如果我删除了ToList(),那么Create()就不会被调用。

3 个答案:

答案 0 :(得分:2)

问题是Select方法实际上并没有那么多。当你迭代它的结果时,它会开始做一些事情。

也就是说,ToList方法会迭代从Select返回的迭代器,因此它会执行你的lambda表达式。

我想您想要获取结果并使用它做一些事情,如果是这样,将其分配给变量并迭代它:

foreach(var row in dtImporteddata.Rows.Cast<DataRow>().Select(...))
{
    // do something with row
}

答案 1 :(得分:2)

LINQ方法可以分为两个阵营:那些总是返回结果的阵营(例如,FirstOrDefault)和那些投射的不同形式的阵营他们。您可以将这些投影方法视为执行过滤操作。

请参阅what is a projection in LINQ, as in .Select()

无论如何,为了回答你的问题,LINQ并不总是执行你认为它正在执行的操作。在许多情况下,LINQ使用后续操作来添加过滤(或修改投影),并且只有在解析时,对结果的方法调用才会执行调用。

我怀疑这是这种情况。如果没有ToList来电,您只需构建指令集,并且只有在您致电ToList时,这些说明才会被解析为结果。

如果您实际上并未对List<DataRow>提供的功能感到困扰,而您只想要一个可枚举的结果,请考虑使用ToArray,因为它的开销低于ToList

答案 2 :(得分:2)

我建议在可重用组件中抽象创建功能,控制器和lambda都可以使用。例如,您可以创建一个具有以下签名的方法的类:

public void CreateDepartment(Department newDepartment)

Department类可能会显示与FormCollection相同的字段。

您可以直接在LINQ中使用新方法,如下所示:

dtImporteddata.Rows.Cast<DataRow>().ToList()
              .ForEach(r => CreateDepartment(
                                new Department {
                                                   Name = r.Name,
                                                   ....//rest of the properties
                                                }));

通过这种方式,您还可以在“创建”操作中调用相同的方法。