有没有人知道我如何从lambda表达式中调用lambda表达式?
如果我有:
public class CourseViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public static Expression<Func<Course, CourseViewModel>> AsViewModel = x =>
new CourseViewModel
{
Id = x.Id,
Name = x.Name,
}
}
public class StudentViewModel
{
public int Id { get; set; }
public string Name{ get; set; }
public string PreferredCheese { get; set; }
public IEnumerable<CourseViewModel> Courses { get; set; }
public static Expression<Func<Student, StudentViewModel>> AsViewModel = x =>
new StudentViewModel
{
Id = x.Id,
Name = x.Name,
PreferredCheese = x.PreferredCheese,
Courses = ???I'd like to call the CourseViewModel.AsViewModel here
}
}
在上面的代码中,而不是在StudentViewModel中编写AsViewModel表达式:
Courses = new CourseViewModel
{
Id = x.Id,
Name = x.Name,
}
我想调用CourseViewModel.AsViewModel以允许代码重用,并保持将Course转换为CourseViewModel类中的CourseViewModel的代码。这可能吗?
答案 0 :(得分:4)
你可以使用x.Courses.Select(c => CourseViewModel.AsViewModel(c))
所以你的整个表达将是:
public static Expression<Func<Student, StudentViewModel>> AsViewModel = x =>
new StudentViewModel
{
Id = x.Id,
Name = x.Name,
PreferredCheese = x.PreferredCheese,
Courses = x.Courses.Select(c => CourseViewModel.AsViewModel(c))
}
答案 1 :(得分:1)
如果要将CourseViewModel.AsViewModel
保存为嵌套表达式(如果使用LINQ查询提供程序,则可能会这样做),这会变得棘手;您实际上必须自己在AsViewModel
中构建StudentViewModel
表达式:
using E = System.Linq.Expressions.Expression; // for brevity
// ...
static StudentViewModel()
{
var s = E.Parameter(typeof(Student), "s");
//
// Quick hack to resolve the generic `Enumerable.Select()` extension method
// with the correct type arguments.
//
var selectMethod = (Expression<Func<Student, IEnumerable<CourseViewModel>>>)
(_ => _.Courses.Select(c => default(CourseViewModel)));
var lambda = E.Lambda<Func<Student, StudentViewModel>>(
E.MemberInit(
E.New(typeof(StudentViewModel)),
E.Bind(
typeof(StudentViewModel).GetProperty("Id"),
E.Property(s, "Id")),
E.Bind(
typeof(StudentViewModel).GetProperty("Name"),
E.Property(s, "Name")),
E.Bind(
typeof(StudentViewModel).GetProperty("PreferredCheese"),
E.Property(s, "PreferredCheese")), // LOL?
E.Bind(
typeof(StudentViewModel).GetProperty("Courses"),
E.Call(
((MethodCallExpression)selectMethod.Body).Method,
E.Property(s, "Courses"),
CourseViewModel.AsViewModel))
),
s);
AsViewModel = lambda;
}
生成的表达式树等同于:
s => new StudentViewModel {
Id = s.Id,
Name = s.Name,
PreferredCheese = s.PreferredCheese,
Courses = s.Courses.Select(x => new CourseViewModel { Id = x.Id, Name = x.Name })
}