[linq] Linq : 조건부로 where 절에 조건 추가

이와 같은 쿼리가 있습니다.

(from u in DataContext.Users
       where u.Division == strUserDiv
       && u.Age > 18
       && u.Height > strHeightinFeet
       select new DTO_UserMaster
       {
         Prop1 = u.Name,
       }).ToList();

이 쿼리를 실행하는 메서드에 해당 조건이 제공되었는지 여부에 따라 연령, 신장과 같은 다양한 조건을 추가하고 싶습니다. 모든 조건에는 사용자 부문이 포함됩니다. 나이가 제공된 경우 쿼리에 추가하고 싶습니다. 마찬가지로 높이가 제공된 경우에도 추가하고 싶습니다.

이것이 SQL 쿼리를 사용하여 수행된다면 문자열 작성기를 사용하여 주 strSQL 쿼리에 추가했을 것입니다. 그러나 여기 Linq에서는 각 IF 블록에 추가 조건이있는 동일한 쿼리를 세 번 작성하는 IF 조건 만 사용할 수 있습니다. 이 작업을 수행하는 더 좋은 방법이 있습니까?



답변

호출하지 않고 ToList()DTO 유형에 대한 최종 매핑을 수행하는 경우 Where계속해서 절을 추가 하고 마지막에 결과를 작성할 수 있습니다 .

var query = from u in DataContext.Users
   where u.Division == strUserDiv
   && u.Age > 18
   && u.Height > strHeightinFeet
   select u;

if (useAge)
   query = query.Where(u => u.Age > age);

if (useHeight)
   query = query.Where(u => u.Height > strHeightinFeet);

// Build the results at the end
var results = query.Select(u => new DTO_UserMaster
   {
     Prop1 = u.Name,
   }).ToList();

이렇게하면 여전히 데이터베이스에 대한 단일 호출 만 발생하며 이는 한 번의 패스로 쿼리를 작성하는 것만 큼 효율적입니다.


답변

나는 일반적으로 메소드 체인을 사용하지만 동일한 문제가 있습니다. 그리고 여기 내가 사용하는 확장이 있습니다.

public static IQueryable<T> ConditionalWhere<T>(
        this IQueryable<T> source,
        Func<bool> condition,
        Expression<Func<T, bool>> predicate)
    {
        if (condition())
        {
            return source.Where(predicate);
        }

        return source;
    }

체인 끊김을 방지하는 데 도움이됩니다. 또한 동일 ConditionalOrderBy하고 ConditionalOrderByDescending도움이됩니다.


답변

하나의 옵션.

bool? age = null

(from u in DataContext.Users
           where u.Division == strUserDiv
           && (age == null || (age != null && u.Age > age.Value))
           && u.Height > strHeightinFeet
           select new DTO_UserMaster
           {
             Prop1 = u.Name,
           }).ToList();

또는 linq의 메소드 구문으로 전환하고 if 조건을 사용하여 표현식을 where 절에 첨부 할 수 있습니다.


답변

단순히 where 절에서 사용하고 있습니다.

    public IList<ent_para> getList(ent_para para){
     db.table1.Where(w=>(para.abc!=""?w.para==para.abc:true==true) && (para.xyz!=""?w.xyz==para.xyz:true==true)).ToList();
}


답변

특정 조건에 따라 where 조건을 추가하십시오 …

from u in DataContext.Users
where u.Division == strUserDiv
&& u.Age != null ? u.Age > 18 : 1== 1
&& u.Height != null ? u.Height > 18 : 1== 1
&& u.Height != null ? u.Height > 18 : 1== 1
 select new DTO_UserMaster
       {
         Prop1 = u.Name,
       }).ToList();


답변

비슷한 작업을 수행하는 코드는 다음과 같습니다. 이것은 내 WCF SOAP 웹 서비스 API의 메서드입니다.

    public FruitListResponse GetFruits(string color, bool? ripe)
    {
        try
        {
            FruitContext db = new FruitContext();
            var query = db.Fruits.Select(f => f);
            if (color != null)
            {
                query = query.Where(f => f.Color == color);
            }
            if (ripe != null)
            {
                query = query.Where(f => f.Ripe == ripe);
            }
            return new FruitListResponse
            {
                Result = query.Select(f => new Fruit { Id = f.FruitId, Name = f.Name }).ToList()
            };
        }
        catch (Exception e)
        {
            return new FruitListResponse { ErrorMessage = e.Message };
        }
    }

기본 쿼리는 Select(f => f)기본적으로 모든 것을 의미하며 Where절이 선택적으로 첨부됩니다. 마지막 Select은 선택 사항입니다. 데이터베이스 행 개체를 결과 “Fruit”개체로 변환하는 데 사용합니다.


답변

다음 매개 변수를 가정하면,

Int? Age = 18;

간단하게 사용 &&||조건 연산자 우리는 다른 버전을 가질 수 있습니다.

(from u in DataContext.Users
where u.Division == strUserDiv
    && (Age == null || u.Age > Age)
    && (Param1 == null || u.param1 == Param1)
    && u.Height > strHeightinFeet
select new DTO_UserMaster
{
    Prop1 = u.Name,
}).ToList();

Param1과 마찬가지로 검색 조건에 대해 여러 매개 변수를 추가 할 수 있습니다.