asp.net - 构建动态 LINQ 查询的最佳方式

标签 asp.net linq

嗨,我正在寻找编写动态 LINQ 查询的最佳方法。

我有一个类似的功能

public IQueryable<Student> FindByAllStudents(int? id, string Name, int? CourseID, bool? IsActive) // like this way, all field values are passed
    {    
        // code for compairision
        return db.Student;
    }

我们也可以写 db.Students.where(predicate)

或者

像这样的查询
var students = from s in db.students where s.Name.Contains(Name)
                s.ID.Equals(id)
                //and so on....

那么,如果我不传递 ID(即 Null),这种方法是否有效?
是所有数据类型的正确方法吗?

重点是函数可以将所有空值作为 select * from 语句等价的参数。

任何人都可以帮助我使用示例代码构建最佳查询吗?

最佳答案

好的,您想要什么并不完全清楚,但是如果您只想为非空参数添加 where 子句,您可以这样做:

public IQueryable<Student> FindByAllStudents
    (int? id, string name, int? courseID, bool? isActive)
{    
    IQueryable<Student> 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;
}

我还没有尝试过,LINQ to SQL 可能会被代码混淆以查找可为空值类型的值。您可能需要编写如下代码:
    if (courseID != null)
    {
        int queryCourseID = courseID.Value;
        query = query.Where(student => student.CourseID == queryCourseID);
    }

不过,值得先尝试更简单的形式:)

当然,这一切都会让人有点恼火。一个有用的扩展方法可以让生活更简洁:
public static IQueryable<TSource> OptionalWhere<TSource, TParameter>
    (IQueryable<TSource> source,
     TParameter? parameter, 
     Func<TParameter, Expression<Func<TSource,bool>>> whereClause)
    where TParameter : struct
{
    IQueryable<TSource> ret = source;
    if (parameter != null)
    {
        ret = ret.Where(whereClause(parameter.Value));
    }
    return ret;
}

然后你会像这样使用它:
public IQueryable<Student> FindByAllStudents
    (int? id, string name, int? courseID, bool? isActive)
{    
    IQueryable<Student> 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;
}

如果您不太习惯使用这样的高阶函数,可能会让人感到困惑,因此如果您没有进行很多这样的查询,您可能希望坚持使用更长但更简单的代码。

关于asp.net - 构建动态 LINQ 查询的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/736952/

相关文章:

c# - 值不能为空。参数名称 : type

c# - 在 GridView 编辑中, "Input string was not in a correct format"

c# - Linq to MySql 按日期分组

c# - 私有(private)化 BlogEngine.Net 安装

c# - Global.asax 在小改动后解析错误并恢复到以前的版本

c# - 转换分割字符串时出错

c# - 将列表传递给 linq 查询

c# - 使用 linq to xml 获取特定值

asp.net - 如何将 ASP.NET Core 应用程序发布到 ftp 服务器

c# - 使用 visual studios 2010 的 asp.net mvc4 教程中的 app_data 中未显示数据库文件