是否可以基于Expression构建部分查询?
public List<SelectListItem> GetSelectedListFromEntity<T>(Expression<Func<T, object>> property) where T : BaseEntity<int>
{
var result = _repository.Query<T>().Select(p => new SelectListItem()
{
Text = property, //? (in simple case it looks like: p.Name + p.Category)
Value = p.Id.ToString(),
).ToList();
return result;
}
有关:
var result = GetSelectedListFromEntity<Product>(p => p.Name + p.Category);
答案 0 :(得分:4)
如果您希望它与数据库提供程序一起工作,那么为您提供IQueryable,您可以使用这样的表达式树做一些事情。
鉴于这些课程:
public class BaseEntity
{
public int Id { get; set;}
}
public class Product : BaseEntity
{
public string Name { get; set; }
public string Category { get; set; }
}
现在你需要一个函数来制作表达式:
public Expression<Func<T, SelectListItem>> CreateExpression<T>(Expression<Func<T, string>> textExp) where T : BaseEntity
{
var arg = textExp.Parameters.First();
var param = new ParameterExpression[] { arg };
var body = Expression.MemberInit(
Expression.New(typeof(SelectListItem)),
Expression.Bind(typeof(SelectListItem).GetMember("Text").First(), textExp.Body),
Expression.Bind(typeof(SelectListItem).GetMember("Value").First(),
Expression.Call(
Expression.PropertyOrField(arg, "Id"),
"ToString",
new Type[0]
)));
var exp = Expression.Lambda(body, param);
return (Expression<Func<T, SelectListItem>>)exp;
}
在C#6中,使用nameof()替换这些魔术字符串会更好。 最后你可以用这样的东西来调用它:
var items = new List<Product> { new Product { Id = 0, Name = "Test", Category = "Cat" } };
var result = items.AsQueryable().Select(CreateExpression<Product>(p => p.Name + p.Category)).ToList();
现在只要你的linq提供者可以应对制作SelectListItems你应该没问题。