简体   繁体   English

如何在Entity Framework Linq查询中注入OR条件?

[英]How to inject OR condition in Entity Framework linq query?

I have two and more if conditions to inject my main query but if the condition has no value (is nullable) I don't want to inject to my query. 我有两个或更多个if条件来注入我的主查询,但是如果条件没有值(可为空),我就不想注入到我的查询中。

For example this is my AND query injection: 例如,这是我的AND查询注入:

// first initialize query can have where or not
var query = context.QuestionInfoes.Include(x =>x.RelationsInfoes).AsQueryable();

// first if condition to inject query
if (filterQuestionInfo.ToProfileId.HasValue)
{
    query = (from q in query 
             join qr in context.QuestionRelationsInfoes on q.Id equals qr.QuestionId 
             where q.BrodcastType == QuestionBrodcastType.All || filterQuestionInfo.ToProfileId == qr.ToProfileId 
             select q);
}

// second if condition to inject AND query and i want to this be OR injection
if (filterQuestionInfo.ProfileId.HasValue)
{
    query = (from q in query 
             where q.ProfileId == filterQuestionInfo.ProfileId 
             select q);
}

Now I want to create "OR" injection and when I call .ToList() , I see just queries in SQL that I needed. 现在,我想创建“ OR”注入,当我调用.ToList() ,只看到我需要的SQL查询。 In top example if ToProfileId and ProfileId have values, I see questions where sent to ToProfileId value and 0 questions from profile id in "ProfileId" value because second query is "And" condition to first query. 在最上面的示例中,如果ToProfileIdProfileId具有值,则我看到的问题发送到ToProfileId值,“ ProfileId”值中的配置文件ID中有0个问题,因为第二个查询是第一个查询的“与”条件。 But I want both of them when I fill both values. 但是当我同时填写两个值时,我都想要它们。

  1. when two values are null: I filtered all of questions (works now) 当两个值都为空时:我过滤了所有问题(现在可以使用)

  2. when one value of ToProfileId or ProfileId is null: I filtered all of questions on that value is not null (works now) 当ToProfileId或ProfileId的一个值为null时:我过滤了对该值的所有问题都不为null(现在可用)

  3. When both value are filled, I want both question list (does not work now) 当两个值都填满时,我想要两个问题列表(现在不起作用)

Note: I don't want to create one query and inject all of my condition in to that query. 注意:我不想创建一个查询并将所有条件插入该查询中。

Assuming QuestionRelationsInfoes exists on QuestionInfoes as a navigation property called QuestionRelationsInfoes , then you dont need the join . 假设QuestionRelationsInfoes作为名为QuestionRelationsInfoes的导航属性存在于QuestionInfoes ,那么您不需要join

Unfortunately, you will have to construct the query based on the 3 scenarios (Both filters set, only 1st filter set, only 2nd filter set). 不幸的是,您将必须基于3种情况(两个过滤器集,仅第一个过滤器集,仅第二个过滤器集)构造查询。

var query = context.QuestionInfoes.Include(x => x.RelationsInfoes);

if (filterQuestionInfo.ToProfileId.HasValue && filterQuestionInfo.ProfileId.HasValue)
{
    query = query.Where(q =>
        q.BrodcastType == QuestionBrodcastType.All ||
        q.QuestionRelationsInfoes.ToProfileId == filterQuestionInfo.ToProfileId ||
        q.ProfileId == filterQuestionInfo.ProfileId);
}
else if (filterQuestionInfo.ToProfileId.HasValue)
{
    query = query.Where(q => q.BrodcastType == QuestionBrodcastType.All || filterQuestionInfo.ToProfileId == q.QuestionRelationsInfoes.ToProfileId);
}
else if (filterQuestionInfo.ProfileId.HasValue)
{
    query = query.Where(q.ProfileId == filterQuestionInfo.ProfileId);
}

As an alternative, if you dislike the code repetition, you can push the check to SQL, by first checking if the filter is not null: 或者,如果您不喜欢重复代码,则可以通过首先检查过滤器是否不为null来将检查推送到SQL:

var query = context.QuestionInfoes.Include(x => x.RelationsInfoes);

if (filterQuestionInfo.ToProfileId.HasValue || filterQuestionInfo.ProfileId.HasValue)
{
    query = query.Where(q =>
        (filterQuestionInfo.ToProfileId.HasValue && (q.BrodcastType == QuestionBrodcastType.All || filterQuestionInfo.ToProfileId == q.QuestionRelationsInfoes.ToProfileId)) ||
        (filterQuestionInfo.ProfileId.HasValue && q.ProfileId == filterQuestionInfo.ProfileId));
}

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

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