Я использую 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