简体   繁体   English

具有Dynamic SQL WHERE子句的实体框架搜索功能

[英]Entity Framework Search functionality with Dynamic SQL WHERE clause

hi guys i was using Dynamic SQL for search queries where i used to attach WHERE & AND clause piece by piece and form a statement, i recently came to below alternate for this, and life was amazing 嗨,大家好,我使用Dynamic SQL进行搜索查询,我曾经将WHEREAND子句逐段附加并形成一条语句,为此我最近来到了下面,这真是太棒了

cool alternates of Dynamic WHERE-Clause 动态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)

now the issue is since i implemented entity framework i need to achieve same with Linq queries. 现在的问题是,因为我实现了实体框架,所以我需要使用Linq查询实现相同的功能。 i have nullable Byte type and nullable boolean which i am currently unable to handle 我有目前无法处理的可为空的字节类型和可为空的布尔值

just like Coalesce my stupid attempt was && (s.Floors == deal.Floors.HasValue ? null : s.Floors) 就像Coalesce一样,我的愚蠢尝试是&& (s.Floors == deal.Floors.HasValue ? null : s.Floors)

below code not matching any results 下面的代码不符合任何结果

[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 has values like 表的值如下

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

i need results which has id 1 & 2 for instance in front end user want to only fill bathroom field with "1" and leave floor field empty 我需要具有ID 1和2的结果,例如在前端用户中,我只想将浴室字段填充为“ 1”,而将地板字段保留为空

You are testing whether the field in the table equals the 'deal' property or the field is null rather than doing this: 您正在测试表中的字段是否等于'deal'属性或该字段为空,而不是这样做:

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

If you do this, it should be the equivalent query. 如果这样做,它应该是等效的查询。

You can do this cumulatively too. 您也可以累积执行此操作。 For example with the exact match case you can do: 例如,在完全匹配的情况下,您可以执行以下操作:

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)

That can make the resulting query more efficient. 这样可以使查询结果更加有效。 There's a similar way to do this with the non exact match through using unions. 有一种类似的方法可以通过使用联合对不完全匹配进行此操作。 I don't know the syntax off hand. 我不了解语法。

Not really the same. 不太一样。 In your query your coalesce is on the parameter then taking the record value as the default if it is null. 在查询中, coalesce是在参数上,然后将记录值作为默认值(如果为空)。 In your c# lambda you are checking if the parameter is the same as the table value and then checking if the table value is null but that omits the possibility of having a null value in the parameter. 在您的C#lambda中,您正在检查参数是否与表值相同,然后检查表值是否为null但这忽略了参数中具有null值的可能性。

Example

Sql SQL

Department = Coalesce(@Department, Department )

would be 将会

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

not this which is what you have now 这不是你现在拥有的

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

Edit 编辑

If you wanted to duplicate the COALESCE expression you have now you could write it this way although I am not sure if it would decrease efficiency / performance. 如果您想复制COALESCE表达式,现在可以用这种方式编写它,尽管我不确定它是否会降低效率/性能。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM