c# - 如何使用表达式构建动态查询(IN 子句)

标签 c# sql entity expression

我有

<!-- language: c# -->
   Expression<Func<TEntity, bool>> 

由属性组成

  • 开始日期日期时间
  • 结束日期日期时间
  • 显示文章 bool
  • 显示 Material bool
  • 显示产品 bool

我想构建动态查询,如下所示:

SELECT * FROM Docs
WHERE StartDate >= @StartDAte 
AND EndDate <= @EndDAte 
AND ArticleInternalType IN (1,2,3)

所有 bool 类型都绑定(bind)到复选框(选中)。 如果用户取消选中复选框查询也应该更改。例如,如果用户取消选中 ShowMaterials 复选框:

SELECT * FROM Docs
WHERE StartDate >= @StartDate 
AND EndDate <= @EndDAte 
AND ArticleInternalType IN (1,3)

这个表达式给出了尴尬的结果

FilterExpression =
f => f.DocumentDate >= StartDate.Date && f.DocumentDate <= EndDate.Date
&& (
showArticles == true ? f.ArticleInternalType == 1 : f.ArticleInternalType == -1 ||
showMaterials == true ? f.ArticleInternalType == 0 : f.ArticleInternalType == -1 ||
showProducts == true ? f.ArticleInternalType == 2 : f.ArticleInternalType == -1
);  

这是 SQLProfiler 的结果

WHERE 
([Extent1].[DocumentDate] >= @p__linq__0) AND ([Extent1].[DocumentDate] <= @p__linq__1) 
AND 
((CASE WHEN (1 = @p__linq__2) THEN 
        CASE WHEN (1 = [Extent1].[ArticleInternalType]) 
                THEN cast(1 as bit) 
             WHEN (1 <> [Extent1].[ArticleInternalType]) 
                THEN cast(0 as bit) 
        END 
        WHEN (1 = @p__linq__3) THEN 
        CASE WHEN (2 = [Extent1].[ArticleInternalType]) 
                THEN cast(1 as bit) 
            WHEN (2 <> [Extent1].[ArticleInternalType]) 
                THEN cast(0 as bit) 
        END 
        WHEN (1 = @p__linq__4) THEN 
        CASE WHEN (3 = [Extent1].[ArticleInternalType]) 
                THEN cast(1 as bit) 
            WHEN (3 <> [Extent1].[ArticleInternalType]) 
                THEN cast(0 as bit) 
        END 
    ELSE cast(0 as bit) 
END) = 1)

有人可以给我建议吗,该怎么做?

最佳答案

您应该能够使用 int 类型列表来完成此操作:

var types = new List<int>();
if (showArticles) types.Add(1);
if (showMaterials) types.Add(0);
if (showProducts) types.Add(2);
FilterExpression = f => f.DocumentDate >= StartDate.Date
    && f.DocumentDate <= EndDate.Date
    && types.Contains(f. ArticleInternalType);

您还可以简化您编写的表达式:

FilterExpression =
f => f.DocumentDate >= StartDate.Date && f.DocumentDate <= EndDate.Date
&& (
    showArticles && f.ArticleInternalType == 1
||  showMaterials && f.ArticleInternalType == 0 
||  showProducts && f.ArticleInternalType == 2
);  

关于c# - 如何使用表达式构建动态查询(IN 子句),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25106530/

相关文章:

c# - Windows 和 IIS 7.5 上的匿名身份验证,允许内部自动登录和外部手动登录

php - MySQL PDO WHERE 语句中的 NULL

c# - 插入查询的 SQL 格式错误

java - 覆盖没有数据库字段映射的实体中的嵌入式 XML 属性

c# - 在 Entity Framework 中使用存储过程,如何让实体填充其导航属性?

c# - 是否可以在一个赋值语句中将多个方法链接到一个委托(delegate)?

c# - 如何平均分配阵列成员

c# - 如何解决 "registered as ' Async Scoped 的生活方式,但实例是在事件(Async Scoped)范围的上下文之外请求的”

mysql - 可以使用 SELECT 查询,但不能使用它来创建新表

c++ - dynamic_cast 返回空指针