Генерация запроса со связанными данными и условиями с использованием выражений LINQ - PullRequest
0 голосов
/ 20 января 2019

У меня есть следующее 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 голосов
/ 20 января 2019

Это поможет, используя отражение, группировка не требуется.

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