繁体   English   中英

使用Linq to sql(EF6)动态撰写选择

[英]Dynamically compose select using Linq to sql (EF6)

是否可以基于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);

如果您希望它与数据库提供程序一起使用,则可以为您提供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 provider可以处理SelectListItems,您就可以了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM