在where子句中构建动态linq查询

本文关键字:动态 linq 查询 构建 where 子句 | 更新日期: 2023-09-27 18:27:19

我想构建一个动态查询,如果对象的值不是空字符串,则该查询能够扩展where子句条件。这是代码

public IEnumerable<Filter> GetFilter(Filter filter)
{
    var y = ConditionalAttribute(filter);
    var query =
        from sub in Subscriptions
        join u in Users
        on sub.UserID equals u.Id
        join od in Order_Details1
        on sub.OD_Id equals od.OD_Id
        join p in Products
        on od.ProductId equals p.ProductId
        where p.Type == "Testing" + y
        select new Filter
        {
            //do something
        };

对于Filter对象,这是代码

public class Filter
{
    public int UserId { get; set; }
    public string FirstName { get; set;}
}

这个想法是如果过滤器。FirstName不为空,它将像下面的一样附加where子句

public String ConditionalAttribute(Filter filter)
{ 
    if(filter.FirstName != "")
        return "&& u.First_Name = " + filter.FirstName + "";           
}

有没有办法像上面的代码一样,一个字符串一个字符串地附加where子句?因为我已经尝试了上面的方法,但它失败了,这要归功于

在where子句中构建动态linq查询

创建尽可能多的动态项,以便在返回IQueryable的小方法中使用。

public IQueryable ConditionalAttribute(IQueryable query, Filter filter)
{ 
    if(filter.FirstName != "") {
        query = query.Where(x => x.First_Name == filter.FirstName);
    }
    return query;
}

然后根据需要在初始LINQ语句之后应用它们:

public IEnumerable<Filter> GetFilter(Filter filter)
{
    var query =
        from sub in Subscriptions
        join u in Users
        on sub.UserID equals u.Id
        join od in Order_Details1
        on sub.OD_Id equals od.OD_Id
        join p in Products
        on od.ProductId equals p.ProductId
        where p.Type == "Testing"
        select new Filter
        {
            //do something
        };
        query = ConditionalAttribute(query, filter);

除非您使用.ToList()或FirstOrDefault()或类似的方法将语句投影到中,否则该语句不会运行,因此您可以根据需要多次以这种方式链接到查询。

我倾向于使用标准的C#语法,而不是LINQ语法,但话虽如此,我发现在连接查询时,LINQ语法更优雅。

这里有一种方法,它利用标准的C#语法来动态过滤源容器,然后使用LINQ语法来创建联接查询。

public IEnumerable<Filter> GetFilter(Filter filter)
{
    var y = ConditionalAttribute(filter);
    IEnumerable<User> filteredUsers = Users;
    if(!string.IsNullOrEmpty(filter.FirstName))
    {
        filteredUsers = filteredUsers.Where(u => u.First_Name == filter.FirstName);
    }
    var query =
        from sub in Subscriptions
        join u in filteredUsers
        on sub.UserID equals u.Id
        join od in Order_Details1
        on sub.OD_Id equals od.OD_Id
        join p in Products
        on od.ProductId equals p.ProductId
        where p.Type == "Testing" + y
        select new Filter
        {
            //do something
        };