【问题标题】:Calling controller Action method using lambda expressions使用 lambda 表达式调用控制器 Action 方法
【发布时间】:2015-05-06 09:44:50
【问题描述】:

我正在尝试在 lambda 表达式中调用控制器操作方法,如下所示。

这里dtImporteddata是我的DataTable

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() 不会被调用。

【问题讨论】:

  • @PatrickHofman Create 是我在控制器中的 Action 方法
  • @PatrickHofman 请查看已编辑的问题

标签: c# asp.net-mvc lambda


【解决方案1】:

问题在于Select 方法实际上并没有做那么多。当您迭代其结果时,它开始做某事。

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

我猜你想获取结果并对其进行处理,如果是这样,请将其分配给一个变量并对其进行迭代:

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

【讨论】:

    【解决方案2】:

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

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

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

    我怀疑这里就是这种情况。如果没有ToList 调用,您只是构建一组指令,只有当您调用ToList 时,这些指令才会解析为结果。

    如果您实际上并不在意 List&lt;DataRow&gt; 提供的功能并且您只是想要一个可枚举的结果,请考虑使用 ToArray,因为它的开销比 ToList 少。

    【讨论】:

      【解决方案3】:

      我建议将创建功能抽象为一个可重用的组件,控制器和您的 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
                                                      }));
      

      这样,您还可以在 Create 操作中调用相同的方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-07-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-02
        • 2016-10-05
        • 1970-01-01
        • 2015-01-22
        相关资源
        最近更新 更多