The best way to build Dynamic LINQ query

后端 未结 1 1539
死守一世寂寞
死守一世寂寞 2021-01-31 06:50

Hi I am looking for best method for writing Dynamic LINQ query.

I have a function like

public IQueryable FindByAllStudents(int? id, string         


        
1条回答
  •  心在旅途
    2021-01-31 07:14

    Okay, it's not entirely clear what you want, but if you're trying to only add where clauses for the parameters which are non-null, you could do:

    public IQueryable FindByAllStudents
        (int? id, string name, int? courseID, bool? isActive)
    {    
        IQueryable query = db.Student;
        if (id != null)
        {
            query = query.Where(student => student.ID == id.Value);
        }
        if (name != null)
        {
            query = query.Where(student => student.Name.Contains(name));
        }
        if (courseID != null)
        {
            query = query.Where(student => student.CourseID == courseID.Value);
        }
        if (isActive != null)
        {
            query = query.Where(student => student.IsActive == isActive.Value);
        }
        return query;
    }
    

    I haven't tried that, and it's possible that LINQ to SQL would get confused by the code to find the value of the nullable value types. You may need to write code like this:

        if (courseID != null)
        {
            int queryCourseID = courseID.Value;
            query = query.Where(student => student.CourseID == queryCourseID);
        }
    

    It's worth trying the simpler form first though :)

    Of course, all this gets a bit irritating. A helpful extension method could make life more concise:

    public static IQueryable OptionalWhere
        (IQueryable source,
         TParameter? parameter, 
         Func>> whereClause)
        where TParameter : struct
    {
        IQueryable ret = source;
        if (parameter != null)
        {
            ret = ret.Where(whereClause(parameter.Value));
        }
        return ret;
    }
    

    You'd then use it like this:

    public IQueryable FindByAllStudents
        (int? id, string name, int? courseID, bool? isActive)
    {    
        IQueryable query = db.Student
            .OptionalWhere(id, x => (student => student.ID == x))
            .OptionalWhere(courseID, x => (student => student.CourseID == x))
            .OptionalWhere(isActive, x => (student => student.IsActive == x));
        if (name != null)
        {
            query = query.Where(student => student.Name.Contains(name));
        }
        return query;
    }
    

    Using a higher order function like this could get confusing if you're not really comfortable with it though, so if you're not doing very many queries like this you might want to stick with the longer but simpler code.

    0 讨论(0)
提交回复
热议问题