Перевести на дерево выражений C # - PullRequest
0 голосов
/ 21 сентября 2019

Я использую c#'s expression tree и пытаюсь создать динамический выбор для наших entity framework запросов.Я все еще на экспериментальной стадии.

Может ли кто-нибудь помочь мне перевести это утверждение в дерево выражений?

  Expression<Func<Person, Person>> ex = x => new Person
            {
                Id = x.Id,
                FirstName = x.FirstName,
                LastName = x.LastName,
                Manager = new Person()
                {
                    Id = x.Id,
                    FirstName = x.Manager.FirstName,
                    LastName = x.Manager.LastName
                },
                Subordinates = x.Subordinates.Select(s => new Person()
                {
                    Id = s.Id,
                    FirstName = s.FirstName,
                    LastName = s.LastName
                }).ToList()
            };

Я уже реализовал большую его часть, за исключением Списка подчиненных.

var param = Expression.Parameter(typeof(Person), "x");

            var createdType = typeof(Person);

            var personObject = Expression.New(createdType);

            var idValue = Expression.PropertyOrField(param, "Id");
            var idProperty = createdType.GetProperty("Id");
            var idAssignment = Expression.Bind(idProperty, idValue);

            var FirstNameValue = Expression.PropertyOrField(param, "FirstName");
            var FirstNameProperty = createdType.GetProperty("FirstName");
            var FirstNameAssignment = Expression.Bind(FirstNameProperty, FirstNameValue);

            var LastNameValue = Expression.PropertyOrField(param, "LastName");
            var LastNameProperty = createdType.GetProperty("LastName");
            var LastNameAssignment = Expression.Bind(LastNameProperty, LastNameValue);

            /* + manager object */
            var managerObject = Expression.New(typeof(Person));
            var managerIdValue = Expression.PropertyOrField(param, "Id");
            var managerIdProperty = createdType.GetProperty("Id");
            var managerIdAssignment = Expression.Bind(managerIdProperty, managerIdValue);

            var managerFirstNameValue = Expression.PropertyOrField(param, "FirstName");
            var managerFirstNameProperty = createdType.GetProperty("FirstName");
            var managerFirstNameAssignment = Expression.Bind(managerFirstNameProperty, managerFirstNameValue);

            var managerLastNameValue = Expression.PropertyOrField(param, "LastName");
            var managerLastNameProperty = createdType.GetProperty("LastName");
            var managerLastNameAssignment = Expression.Bind(managerLastNameProperty, managerLastNameValue);

            var managerMemberAssignments = new List<MemberAssignment>()
            {
                managerIdAssignment,
                managerFirstNameAssignment,
                managerLastNameAssignment
            };
            var managerObjectInit = Expression.MemberInit(managerObject, managerMemberAssignments);

            var managerProperty = createdType.GetProperty("Manager");
            var managerAssignment = Expression.Bind(managerProperty, managerObjectInit);
            /* - manager object */

            /* + subordinates list */
            var s = Expression.Parameter(typeof(Person), "s");
            var subordinateObject = Expression.New(typeof(Person));

            var subordinateIdValue = Expression.PropertyOrField(s, "Id");
            var subordinateIdProperty = createdType.GetProperty("Id");
            var subordinateIdAssignment = Expression.Bind(subordinateIdProperty, subordinateIdValue);

            var subordinateFirstNameValue = Expression.PropertyOrField(s, "FirstName");
            var subordinateFirstNameProperty = createdType.GetProperty("FirstName");
            var subordinateFirstNameAssignment = Expression.Bind(subordinateFirstNameProperty, subordinateFirstNameValue);

            var subordinateLastNameValue = Expression.PropertyOrField(s, "LastName");
            var subordinateLastNameProperty = createdType.GetProperty("LastName");
            var subordinateLastNameAssignment = Expression.Bind(subordinateLastNameProperty, subordinateLastNameValue);

            var subordinateListMemberAssignments = new List<MemberAssignment>()
            {
                subordinateIdAssignment,
                subordinateFirstNameAssignment,
                subordinateLastNameAssignment
            };

            var subordinateObjectInit = Expression.MemberInit(subordinateObject, subordinateListMemberAssignments);
            var subordinateLambda = Expression.Lambda<Func<Person, Person>>(subordinateObjectInit, s);


            var subordinatesValue = Expression.PropertyOrField(param, "Subordinates");
            var subordinatesSelect = Expression.Call()
            var subordinatesProperty = createdType.GetProperty("Subordinates");
            var subordinatesAssignment = Expression.Bind(subordinatesProperty, subordinateObjectInit);


            /* - subordinates list */

            var personMemberAssignments = new List<MemberAssignment>()
            {
                idAssignment,
                FirstNameAssignment,
                LastNameAssignment,
                managerAssignment,
                subordinatesAssignment
            };
            var personInit = Expression.MemberInit(personObject, personMemberAssignments);


            var personLambda = Expression.Lambda<Func<Person, Person>>(personInit, param);

            var result = await _applicationDbContext.Persons.Select(personLambda).ToListAsync();

моя проблема в этой части здесь.

var subordinatesValue = Expression.PropertyOrField(param, "Subordinates");
            var subordinatesSelect = Expression.Call()
            var subordinatesProperty = createdType.GetProperty("Subordinates");
            var subordinatesAssignment = Expression.Bind(subordinatesProperty, subordinateObjectInit);

Понятия не имею, как перевести это в выражение.

Subordinates = x.Subordinates.Select(s => new Person()
                {
                    Id = s.Id,
                    FirstName = s.FirstName,
                    LastName = s.LastName
                }).ToList()

это ужедочерняя собственность объекта Person

...