2013-02-06 37 views
4

我使用asp.mvc 4. Assumend我有一個叫人用領域 ASP MVC剃刀存儲lambda表達式列出和重用

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; } 
} 

在我的自動生成的剃刀編輯視場模式如圖所示(爲了清楚,我只包括在這個崗位重要行)

@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) 
} 

回答

0

你試過來存儲這樣的拉姆達:

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); 
+0

謝謝,但這是行不通的。這導致編譯錯誤。你用這種方法成功了嗎? –

+0

是的,它在控制檯解決方案中工作正常。我認爲Razor不支持它,或者? – Smartis

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) 
} 
+0

感謝您的建議。是的,看起來不錯,但我的主要目標是瞭解如何將lambda表達式存儲到列表中並稍後使用它; –

+0

您不能將它存儲在列表中,因爲您不知道lambda表達式的確切類型。你可以使用'Expression >',但這不適用於ASP。如果您嘗試在模型上使用值爲type的屬性(如DateTime或整數),則可以使用「DisplayFor」等NET MVC幫助程序, –

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) 
} 
0

要通過在Razor視圖模特屬性循環,你應該使用ViewData.ModelMetadata.Properties作爲this answer。例如:

@* Loop through properties. *@ 
@foreach (var property in ViewData.ModelMetadata.Properties) 
{ 
    @Html.Display(property.PropertyName) 
}