【问题标题】:Entity Framework Search functionality with Dynamic SQL WHERE clause具有动态 SQL WHERE 子句的实体框架搜索功能
【发布时间】:2017-01-21 03:34:16
【问题描述】:

嗨,伙计们,我使用动态 SQL 进行搜索查询,我曾经在其中逐个附加 WHEREAND 子句并形成一个语句,我最近来到下面的替代品,生活真是太棒了

cool alternates of Dynamic WHERE-Clause

Select * From tblEmployees 
where EmployeeName = Coalesce(@EmployeeName, EmployeeName) AND
Department = Coalesce(@Department, Department ) AND
Designation = Coalesce(@Designation, Designation) AND
JoiningDate >= Coalesce(@StartDate, JoiningDate) AND 
JoiningDate <= Coalesce(@EndDate, JoiningDate) AND
Salary >= Coalesce(@Salary, Salary)

现在的问题是,因为我实现了实体框架,所以我需要用 Linq 查询来实现相同的目标。我有可空的字节类型和可空的布尔值,我目前无法处理

就像Coalesce 我的愚蠢尝试是 &amp;&amp; (s.Floors == deal.Floors.HasValue ? null : s.Floors)

以下代码不匹配任何结果

[HttpPost]
        public ActionResult Results(Deal deal, bool exactMatch)
    {
        List<Deal> deals;

        if (exactMatch)
        {
            deals = dataBase.Deals.Where(s =>
               (s.OwnerName.Contains(deal.OwnerName) || s.OwnerName == null)
            && (s.Rooms == deal.Rooms || s.Rooms == null)
            && (s.BathRooms == deal.BathRooms || s.BathRooms == null)
            && (s.Floors == deal.Floors || s.Floors == null)
            && (s.Builtin == deal.Builtin || s.Builtin == null)
            && (s.Kitchens == deal.Kitchens || s.Kitchens == null)
            && (s.DoubleUnit == deal.DoubleUnit || s.DoubleUnit == null)
            && (s.Corner == deal.Corner || s.Corner == null)
            && (s.Remarks.Contains(deal.Remarks) || s.Remarks == null)
            ).ToList();
        }
        else
        {
            deals = dataBase.Deals.Where(s =>
               (s.OwnerName.Contains(deal.OwnerName) || s.OwnerName == null)
            || (s.Rooms == deal.Rooms || s.Rooms == null)
            || (s.BathRooms == deal.BathRooms || s.BathRooms == null)
            || (s.Floors == deal.Floors || s.Floors == null)
            || (s.Builtin == deal.Builtin || s.Builtin == null)
            || (s.Kitchens == deal.Kitchens || s.Kitchens == null)
            || (s.DoubleUnit == deal.DoubleUnit || s.DoubleUnit == null)
            || (s.Corner == deal.Corner || s.Corner == null)
            || (s.Remarks.Contains(deal.Remarks) || s.Remarks == null)
            ).ToList();
        }

        return View(deals);
    } 

table 有类似的值

id Bathroom Floors
1   1        2
2   1        4
3   2        6
4   3        1

我需要 id 为 1 和 2 的结果 例如在前端用户只想用“1”填充浴室字段并将地板字段留空

【问题讨论】:

  • @AntoinePelletier 区别在于 && 和 II
  • 并不完全一样。在您的查询中,您的 coalesce 位于参数上,如果记录值为空,则将其作为默认值。在您的 c# lambda 中,您正在检查参数是否与表值相同,然后检查表值是否为 null,但这忽略了参数中包含空值的可能性。
  • @Igor 我将 coalesce 转换为 c# 代码是一个蹩脚的尝试,我只需要 C# 中的类似 coalesce 的功能
  • 您应该从表达式主体中删除这些空检查。动态构建表达式:stackoverflow.com/a/14622200/861716
  • 特别是。对于|| 替代方案,您必须按照我上面提到的方法进行操作。请注意,即使只有一个 = null 条件为真,它也总是返回所有行。

标签: c# entity-framework linq tsql


【解决方案1】:

其实不太一样。在您的查询中,您的 coalesce 位于参数上,如果记录值为空,则将其作为默认值。在您的 c# lambda 中,您正在检查参数是否与表值相同,然后检查表值是否为 null,但这忽略了参数中包含空值的可能性。

例子

SQL

Department = Coalesce(@Department, Department )

应该是

(s.Department == deal.Department || deal.Department == null)

这不是你现在拥有的

(s.Department == deal.Department || s.Department == null)

编辑

如果您想复制您现在拥有的 COALESCE 表达式,您可以这样写,但我不确定它是否会降低效率/性能。

(s.Department == (deal.Department ?? s.Department))

【讨论】:

  • 让我测试一下这两个??声明和 (s.Department == deal.Department || deal.Department == null)
  • @AbubakarRiaz - 好的。
  • ?? 肯定有效我已经检查过(s.Department == (deal.Department ?? s.Department)) 已在 SQL 案例语句中转换,并适合我在此搜索功能中的需要。 ([Extent1].[Department] = CASE WHEN (@p__linq__28 IS NULL) THEN [Extent1].[Department] ELSE @p__linq__28 END )
  • 非常感谢您这么快的回复。
【解决方案2】:

您正在测试表中的字段是否等于“交易”属性或该字段是否为空,而不是这样做:

s.Remarks.Contains(deal.Remarks) || deal.Remarks == null

如果你这样做,它应该是等效的查询。

您也可以累积执行此操作。例如,您可以使用完全匹配的情况:

deals = dataBase.Deals;
if (deal.OwnerName != null)
   deals = deals.Where(s => s.OwnerName.Contains(deal.OwnerName));

if (deal.Rooms != null)
  deals = deals.Where(s => s.Rooms == deal.Rooms)

这可以使生成的查询更有效率。有一种类似的方法可以通过使用联合来处理非精确匹配。我不知道手头的语法。

【讨论】:

  • 是的,EF查询的一个重要方面,如果你选择s =&gt; 那么s会一直引用表
猜你喜欢
  • 2010-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-31
  • 2011-05-11
  • 1970-01-01
相关资源
最近更新 更多