使用 LINQ 表达式生成具有相关数据和条件的查询

Generating a query with related data and conditions using LINQ expressions

我有以下重现,其中 returns 所有 MyParent 对象的 Name 具有相关的 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;
    }
}

这将使用反射来解决问题,不需要分组。

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