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

时间:2019-01-20 16:41:46

标签: c# linq linq-expressions

我有以下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;
    }
}

1 个答案:

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