c# - 在 Linq.Table.Where() 中使用可选 OR 子句

标签 c# asp.net linq-to-sql lambda

有没有办法让 ProjectID 检查可选 block 的下面部分?我是最近从 Java EE 转换为 .Net 的人,我正在寻找类似于 Hibernate Criteria API 的东西。我想简化下面的 block ,只需要调用一次Where()。我也不确定使用 lambda 执行Where() 对性能的影响,因为我一周前才开始使用 .Net。

public IQueryable<Project> FindByIdOrDescription(string search)
    {
        int projectID;
        bool isID = int.TryParse(search, out projectID);

        IQueryable<Project> projects;

        if (isID)
        {
            projects = dataContext.Projects.Where(p => p.ProjectDescription.Contains(search) || p.ProjectID == projectID);
        }
        else
        {
            projects = dataContext.Projects.Where(p => p.ProjectDescription.Contains(search));
        }

        return projects;
    }

最佳答案

如果您正在寻找选择性添加 AND xyz,您可以简单地链接 Where 调用:

var projects = dataContext.Projects.Where(p => p.ProjectDescription.Contains(search));
if (isID)
    projects = projects.Where(p => p.ProjectID == projectID);

不幸的是,当您想要执行OR xyz时,事情并不那么容易。为此,您需要手动构建谓词表达式。 这不太漂亮。实现此目的的一种方法是

Expression<Func<Project, bool>> predicate = p => p.ProjectDescription.Contains(search);
if (isID)
{
    ParameterExpression param = expr.Body.Parameters[0];
    predicate = Expression.Lambda<Func<Project, bool>>(
        Expression.Or(
            expr.Body,
            Expression.Equal(
                Expression.Property(param, "ProjectID"),
                Expression.Constant(projectID))),
        param);
}
var projects = dataContext.Projects.Where(predicate);

请注意,向现有谓词添加条件比创建初始表达式需要更多工作,因为我们需要完全重建表达式。 (谓词必须始终使用单个参数;使用 lambda 语法声明两个表达式将创建两个单独的参数表达式对象,每个谓词一个。)请注意,当您对初始值使用 lambda 语法时,C# 编译器在幕后执行的操作大致相同。谓词。

请注意,如果您习惯了 Hibernate 的标准 API,这可能看起来很熟悉,只是稍微冗长一点。


但是请注意,某些 LINQ 实现非常智能,因此以下内容也可能有效:

var projects = dataContext.Projects.Where(
    p => p.ProjectDescription.Contains(search)
      || (isID && p.ProjectID == projectID));

不过,YMMV,所以请检查生成的 SQL。

关于c# - 在 Linq.Table.Where() 中使用可选 OR 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1626304/

相关文章:

c# - ASP.NET MVC3 自定义成员资格提供程序 - 指定的成员资格提供程序名称无效

javascript - 如何将 html5 Canvas 图像保存到 mssql varbinary(max) 字段?

c# - Modal RadWindow 未在 Chrome 中关闭

c# - 关联表和 Linq to Sql

.net - 如何在 LINQ 查询中使用 GROUP BY 获取 MAX 行?

c# - 如何设置 DateTime 小时、分钟和秒?

C# 为什么使用实例方法作为委托(delegate)分配 GC0 临时对象但比缓存委托(delegate)快 10%

c# - 使用 .net http2 的 Apple 推送通知

c# - 部署到服务器时出现目录未找到异常

c# - 根据 LINQ to SQL 中的变量选择列