我对具有多个链接表的数据库进行LINQ查询,并且需要根据输入返回(选择)不同的字段。
ClassA has ParamA, ParamB, and ICollection<ClassB>ClassBs
ClassB has ParamD, ParamE
Linq查询的部分:
.Select(c => new ClassA()
{
ParamA = c.ParamA,
ParamB = c.ParamB,
ClassBs = c.ClassBs.Select(p => new ClassB()
{
ParamD = p.ParamD,
ParamE = p.ParamE
}).ToList()
}).ToList();
在某些电话上,我只需要ParamA和ParamE。在其他调用上,可能是ParamB和ParamE。我已经可以使用Expressions来完成这项工作,但不能用于ICollection。我尝试使用Dynamic.Linq.Core,但在SELECT中找不到用于更新的任何示例。我更喜欢使用MemberExpressions ...
[更新] 更多上下文:ClassA和ClassB本质上是指向SQL表的EF模型。 ClassA与ClassB有一对多关系,因此,为什么我要以这种方式查询它们。班级A将是一个学生记录(姓名,地址,家庭等),班级B将是一个测试记录,其中学生可能有一个以上的考试,每个考试都有日期,成绩,等级,最高分数得分,最低分数得分等等。 >
我并不总是想要两个表的所有字段,因为可能有100万条记录,因此,为什么我只选择SELECT所需的特定查询和操作所需的内容。
答案 0 :(得分:0)
这可能有点冗长,但是表达式可以使用这种方式,例如:
var typeClassA = typeof(ClassA);
var typeClassB = typeof(ClassB);
var parameterExpressionP = Expression.Parameter(typeClassB, "p");
var newExpression = Expression.New(typeClassB);
var paramDPropertyExpression = Expression.Property(parameterExpressionP, "ParamD");
var paramDMemberBinding = Expression.Bind(typeClassB.GetProperty("ParamD"), paramDPropertyExpression);
var paramEPropertyExpression = Expression.Property(parameterExpressionP, "ParamE");
var paramEMemberBinding = Expression.Bind(typeClassB.GetProperty("ParamE"), paramEPropertyExpression);
var memberInitExpression = Expression.MemberInit(
newExpression,
paramDMemberBinding, paramEMemberBinding);
var projectionExpression = Expression.Lambda<Func<ClassB, ClassB>>(memberInitExpression, parameterExpressionP);
var parameterExpressionC = Expression.Parameter(typeClassA, "c");
var selectParamExpression = Expression.Property(parameterExpressionC, "ClassBs");
var selectExpression = Expression.Call(
typeof(Enumerable),
nameof(Enumerable.Select),
new[] { typeClassB, typeClassB },
selectParamExpression, projectionExpression);
var toListExpression = Expression.Call(
typeof(Enumerable),
nameof(Enumerable.ToList),
new[] { typeClassB },
selectExpression);
这将创建类似以下内容的表达式:
c.ClassBs.Select(p => new ClassB() {ParamD = p.ParamD, ParamE = p.ParamE}).ToList()