在我的应用程序中,某些表需要多个报告,许多字段在大多数报告中都很常见,作为示例:
public class ReportStudent
{
public int Id {get; set;}
public string Name {get; set;}
public string Family {get; set;}
public DateTime BirthDate {get; set;}
public DateTime RegisterDate {get; set;}
public Double Average {get; set;}
public string FatherName {get; set;}
public string MotherName {get; set;}
}
var list1 = context.Students.Select(e=> new ReportStudent
{
Id = e.Id
Name = e.Name
Family = e.Family
BirthDate = e.BirthDate
RegisterDate = e.RegisterDate
FatherName = e.FatherName
MotherName = e.MotherName
}).ToList();
var list2 = context.Students.Select(e=> new ReportStudent
{
Id = e.Id
Name = e.Name
Family = e.Family
BirthDate = e.BirthDate
RegisterDate = e.RegisterDate
Average = e.Average
}).ToList();
我怎么才能只写一次这张地图?这些字段在list1和list2中很常见。
Id = e.Id
Name = e.Name
Family = e.Family
BirthDate = e.BirthDate
RegisterDate = e.RegisterDate
答案 0 :(得分:4)
首先,定义一个包含常见投影需求的表达式:
Expression<Func<ReportStudent, ReportStudent>> commonProjection = e => new ReportStudent
{
Id = e.Id,
Name = e.Name,
Family = e.Family,
BirthDate = e.BirthDate,
RegisterDate = e.RegisterDate,
};
然后有一个方法将修改此表达式以反映其他绑定:
public static Expression<Func<ReportStudent, ReportStudent>> MergeBindings(Expression<Func<ReportStudent, ReportStudent>> expr, Expression<Func<ReportStudent, ReportStudent>> newExpr)
{
var reportStudentType = typeof(ReportStudent);
var eParameter = expr.Parameters.First();
var eNew = Expression.New(reportStudentType);
var memberInitExpr = expr.Body as MemberInitExpression;
var memberInitNewExpr = newExpr.Body as MemberInitExpression;
var allBindings = memberInitExpr.Bindings.Concat(memberInitNewExpr.Bindings.Select(x =>
Expression.Bind(x.Member, Expression.Property(eParameter, x.Member as PropertyInfo)
)));
var eInit = Expression.MemberInit(eNew, allBindings);
var lambda = Expression.Lambda<Func<ReportStudent, ReportStudent>>(eInit, eParameter);
return lambda;
}
用法:
var withParentsExpr = MergeBindings(commonProjection, e => new ReportStudent
{
FatherName = e.FatherName,
MotherName = e.MotherName
});
var list1 = context.Students.Select(withParentsExpr).ToList();
var withAverageExpr = MergeBindings(commonProjection, e => new ReportStudent
{
Average = e.Average
});
var list2 = context.Students.Select(withAverageExpr).ToList();
(在@Nicholas Butler great answer的帮助下)
答案 1 :(得分:0)
如果您不想每次都写地图,可以使用优秀的图书馆http://automapper.org/ 使用此库,您可以定义地图并自动映射所有属性
答案 2 :(得分:0)
你可以创建一个函数,假设你有
public StudentReport ParseStudentReport(Student e)
{
return new StutentReport{
Id = e.Id
Name = e.Name
Family = e.Family
BirthDate = e.BirthDate
RegisterDate = e.RegisterDate
}
}
然后在您的select语句中使用它
var list2 = context.Students.Select(ParseStudentReport);
然后添加剩余的属性,或者您可以使用AutoMapper,它可以在github上找到,也可以作为nuget包。