#c# #asp.net #expression
#c# #asp.net #выражение
Вопрос:
У меня есть два выражения, подобных этому:
Expression<Func<T, T> exp1 = x => new T { Id = 1 , Name = "string"}
Expression<Func<T, T> exp2 = x => new T { Age = 21 }
Как я могу их объединить?
Результат:
Expression<Func<T, T> exp3 = x => new T { Id = 1 , Name = "string" , Age = 21}
T — это : IEntityBaseRepository<T> where T : class, IEntityBase, new()
IEntityBase:
public interface IEntityBase
{
string Id { get; set; }
string Name { get; set; }
int Age { get; set; }
}
public virtual async Task UpdateAsync(string id, Expression<Func<T, T>> updateFactory)
{
Expression<Func<T, T>> updateFactory2 = s => new T { age = 21 };
//Expression<Func<T, T>> updateFactoryFinal = updateFactory updateFactory2;
await _context.Set<T>().Where(w => w.Id == id).UpdateAsync(updateFactoryFinal);
}
Комментарии:
1. Это не компилируется. Что такое
T
?2. @PatrickHofman T — это: IEntityBaseRepository<T> где T : класс, IEntityBase, new()
3. @m.h.bayan — Нет, это то, чем
T
ограничиваются. Это не то, чтоT
есть.4. Этот вопрос слишком широкий. Здесь нужно много чего сделать, например, извлечь тело каждого выражения, проанализировать его, определить дубликаты — кстати, как с ними обращаться — … Например. что, если
Age
указаны оба выражения?5. Вы должны реализовать собственное выражение visitor. Проверьте MS docs (класс ExpressionVisitor) для получения подробной информации. Найдите примеры в Интернете.
Ответ №1:
Поскольку вы никогда не используете Func
аргумент, вы можете упростить свой код и использовать Func<T>
. Следующий метод объединит два (или более) выражения MemberInitExpression
в одно:
public static Expression<Func<T>> MergeExpressions<T>(params Expression<Func<T>>[] expressions)
where T : new()
{
var allBindings = new List<MemberBinding>();
foreach (var expression in expressions)
{
var bindings = ((MemberInitExpression) expression.Body).Bindings;
allBindings.AddRange(bindings);
}
var body = Expression.MemberInit(Expression.New(typeof(T)), allBindings);
return Expression.Lambda<Func<T>>(body);
}
Вы можете проверить это онлайн здесь
Комментарии:
1. используйте метод UpdateAsync, просто получите Func<T, T> entityframework-plus.net пакет
2. @m.h.bayan чтобы заставить это работать,
Func<T, T>
просто заменитеFunc<T>
и отредактируйте последнюю строку наExpression.Lambda<Func<T>>(body, Expression.Parameter(typeof(T)));