4

我正在使用 asp.mvc 4。假设我有一个名为 Person 的模型,其中包含字段

public class Person
{
    public int ID { get; set; }
    public string FirstName { get; set; }
    public string SecondName { get; set; }
    public DateTime DateOfBirth { get; set; }
    public DateTime DateOfWorkstart { get; set; }
    public int NumberOfChildren { get; set; }
    public int DepartmentID { get; set; }
    public virtual Department Department { get; set; }
}

public class Department
{
    public int ID { get; set; }
    public int NameOfDepartment { get; set; }
}

在我自动生成的 razor-edit-view 字段中显示如下(为了清楚起见,我只在这篇文章中包含了重要的行)

@Html.DisplayFor(modelItem => item.FirstName)
@Html.DisplayFor(modelItem => item.SecondName)

现在我想将 linq-lambda 表达式存储在一个列表中以供以后使用,我不知道该怎么做,我需要这样的东西:

@{
    string itemsToShow = "namepart"; // this could also be "otherpart"
    List <Expression<>> list = new List();
    if (itemsToShow.equals("namepart")
    {
        list.add(modelItem => item.FirstName);
        list.add(modelItem => item.SecondName);
    }
    else
    {
        list.add(modelItem => item.DateOfBirth);
        list.add(modelItem => item.DateOfWorkStart);
        list.add(modelItem => item.NumberOfChildren);
    }
}

最后我想像这样使用生成的列表

@foreach (var lambda in list)
{
    @Html.DisplayFor(lambda)
}
4

4 回答 4

1

我的大脑有一点点进步。感谢您的建议。正如@darin-dimitrov 所说,秘诀是存储一个表达式树。我更新了我的第一篇文章并添加了一个相关表格。此示例仅在模型已从数据库表中获取“1 单行”时才有效,例如在编辑视图中;

// first a small helper, which creates the member and checks nullable fields
public static Expression getExpressionPart(ParameterExpression param,
  String s1, String s2)
{
    Expression member = null;
    if (s2 == null)
    {
        member = Expression.Property(param, s1);
    }
    else
    {
        // the second string is to deal with foreign keys/related data
        member = Expression.PropertyOrField(
          Expression.PropertyOrField(param, s1), s2
        );
    }

    Type typeIfNullable = Nullable.GetUnderlyingType(member.Type);
    if (typeIfNullable != null)
    {
        member = Expression.Call(member, "GetValueOrDefault", Type.EmptyTypes);
    }
}

现在创建列表和表达式

List<Expression<Func<Person, object>>> list =
  new List<Expression<Func<Person, object>>>();
ParameterExpression param = Expression.Parameter(typeof(Person), "p");

// maps to expression p => p.FirstName
Expression member = getExpressionPart(param, "Firstname", null);
list.Add(Expression.Lambda<Func<Person, object>>(member, param));

// maps to expression p => p.Department.NameOfDepartment
member = getExpressionPart(param, "Department", "NameOfDepartment");
list.Add(Expression.Lambda<Func<Person, object>>(member, param));

现在它可以工作了!

@foreach (var lambda in list)
{
    @Html.DisplayNameFor(lambda)
    @Html.DisplayFor(lambda)
}
于 2013-02-07T10:07:25.750 回答
1

我会为此编写一个自定义助手:

public static class HtmlExtensions
{
    public static IHtmlString MyHelper(this HtmlHelper<MyViewModel> html, string itemsToShow)
    {
        var sb = new StringBuilder();
        if (itemsToShow == "namepart")
        {
            sb.Append(html.DisplayFor(x => x.FirstName));
            sb.Append(html.DisplayFor(x => x.SecondName));
        }
        else
        {
            sb.Append(html.DisplayFor(x => x.DateOfBirth));
            sb.Append(html.DisplayFor(x => x.DateOfWorkStart));
            sb.Append(html.DisplayFor(x => x.NumberOfChildren));
        }
        return new HtmlString(sb.ToString());
    }
}

然后在视图中简单地:

@Html.MyHelper("namepart")

如果你想渲染另一部分:

@Html.MyHelper("otherpart")

作为替代方案,只需将此内容放入 2 个不同的局部视图中,然后:

@if (itemsToShow == "namepart")
{
    @Html.Partial("_NamePart", Model)
}
else
{
    @Html.Partial("_OtherPart", Model)
}
于 2013-02-06T09:33:15.410 回答
0

您是否尝试过像这样存储 lambda:

Func<Person,bool> personExpression = (u => u.FirstName == firstname);

@Html.DisplayFor(personExpression)

对于 2 种输入类型,您的代码将如下所示:

Func<Person,Ticket,bool> personExpression =
        ((u,t) => u.FirstName == firstname && u.SecondName == t.SecondName);
于 2013-02-06T09:13:52.110 回答
0

要在剃刀视图中循环浏览模型属性,您应该ViewData.ModelMetadata.Properties此答案中使用。例如:

@* Loop through properties. *@
@foreach (var property in ViewData.ModelMetadata.Properties)
{
    @Html.Display(property.PropertyName)
}
于 2017-07-18T20:05:46.837 回答