我有以下repro,它返回所有Name
对象的MyParent
和相关的MyChild
,其中指定字段(仅在运行时已知)为true
该示例有效,但是我敢肯定有足够的空间来简化查询。测试案例中删除了许多不相关的数据,例如元数据和导航属性。实际的数据存储是mssql数据库。可以避免团体建设吗?
using System;
using System.Linq;
using System.Linq.Expressions;
public class MyParent
{
public int Id { get; set; }
public string Name { get; set; }
public bool Enabled { get; set; }
}
public class MyChild
{
public int Id { get; set; }
public bool FieldA { get; set; }
public bool FieldB { get; set; }
public int MyParentId { get; set; }
}
class Program
{
static void Main()
{
var childA = new MyChild { Id = 0, FieldA = false, MyParentId = 0 };
var parentA = new MyParent { Id = 0, Name = "John", Enabled = true };
var childB = new MyChild { Id = 1, FieldA = true, MyParentId = 1 };
var parentB = new MyParent { Id = 1, Name = "Jane", Enabled = true };
var userField = "FieldA";
var parents = new[] { parentA, parentB }.AsQueryable();
var children = new[] { childA, childB }.AsQueryable();
var parameter = Expression.Parameter(typeof(MyChild), "p");
var property = Expression.Property(parameter, userField);
var lambda = Expression.Lambda<Func<MyChild, bool>>(property, parameter);
var query =
from parent in parents
join child in children on parent.Id equals child.MyParentId into grp
from g in grp.AsQueryable().Select(lambda).Where(p => p)
where parent.Enabled
select parent.Name;
}
}
答案 0 :(得分:0)
这将通过反射来实现,不需要分组。
static void Main()
{
var childA = new MyChild { Id = 0, FieldA = false, MyParentId = 0 };
var parentA = new MyParent { Id = 0, Name = "John", Enabled = true };
var childB = new MyChild { Id = 1, FieldA = true, MyParentId = 1 };
var parentB = new MyParent { Id = 1, Name = "Jane", Enabled = true };
var parents = new[] { parentA, parentB }.AsQueryable();
var children = new[] { childA, childB }.AsQueryable();
var userField = "FieldA";
var childQuery = from child in children.Where(c => c.GetType().GetProperty(userField).GetValue(c).Equals(true)) select child;
var query =
from parent in parents
join child in childQuery on parent.Id equals child.MyParentId
where parent.Enabled
select parent.Name;
}