[linq] Linq to SQL “(값 목록)에서 [열] 위치”수행 방법

ID 목록을 가져 오는 함수가 있으며 ID와 관련된 설명과 일치하는 목록을 반환해야합니다. 예 :

public class CodeData
{
    string CodeId {get; set;}
    string Description {get; set;}
}

public List<CodeData> GetCodeDescriptionList(List<string> codeIDs)
    //Given the list of institution codes, return a list of CodeData
    //having the given CodeIds
}

따라서 직접 SQL을 생성하는 경우 다음과 같이 간단히 수행합니다 (in 절에 codeIds 인수의 모든 값이 포함됨).

Select CodeId, Description FROM CodeTable WHERE CodeId IN ('1a','2b','3')

Linq to Sql에서 “IN”절에 해당하는 것을 찾을 수 없습니다. 지금까지 찾은 것 중 최고 (작동하지 않음)는 다음과 같습니다.

 var foo = from codeData in channel.AsQueryable<CodeData>()
           where codeData.CodeId == "1" || codeData.CodeId == "2"
           select codeData;

문제는 linq to sql에 대한 “OR”절 목록을 동적으로 생성 할 수 없다는 것입니다. 왜냐하면 그것들은 컴파일 타임에 설정되기 때문입니다.

Linq to Sql을 사용하여 동적 값 목록에 열이 있는지 확인하는 where 절을 어떻게 수행합니까?



답변

사용하다

where list.Contains(item.Property)

또는 귀하의 경우 :

var foo = from codeData in channel.AsQueryable<CodeData>()
          where codeIDs.Contains(codeData.CodeId)
          select codeData;

그러나 점 표기법으로하는 것이 좋습니다.

var foo = channel.AsQueryable<CodeData>()
                 .Where(codeData => codeIDs.Contains(codeData.CodeId));


답변

다음을 사용할 수도 있습니다.

List<int> codes = new List<int>();

codes.add(1);
codes.add(2);

var foo = from codeData in channel.AsQueryable<CodeData>()
          where codes.Any(code => codeData.CodeID.Equals(code))
          select codeData;


답변

나는 Jon Skeet의 답변에서 방법을 사용하고 있었지만 Concat. 이 Concat방법은 제한된 테스트에서 약간 더 잘 수행되었지만 번거롭고 아마도 Contains. 어느 쪽이든 관심이있는 사람이 있다면 다음과 같은 또 다른 옵션이 있습니다.

방법

// Given an array of id's
var ids = new Guid[] { ... };

// and a DataContext
var dc = new MyDataContext();

// start the queryable
var query = (
    from thing in dc.Things
    where thing.Id == ids[ 0 ]
    select thing
);

// then, for each other id
for( var i = 1; i < ids.Count(); i++ ) {
    // select that thing and concat to queryable
    query.Concat(
        from thing in dc.Things
        where thing.Id == ids[ i ]
        select thing
    );
}

성능 테스트

이것은 원격으로 과학적이지 않았습니다. 데이터베이스 구조와 목록에 포함 된 ID의 수가 상당한 영향을 미칠 것이라고 생각합니다.

각각 100 번의 시도를 수행 Concat하고 Contains각 시도가 무작위 기본 키 목록에 지정된 25 개의 행을 선택 하는 테스트를 설정했습니다 . 나는 이것을 약 12 ​​번 실행했고, 대부분의 경우 Concat방법이 5-10 % 더 빨리 나왔지만 한 번은 Contains방법이 smidgen에 의해 이겼습니다.


답변

 var filterTransNos = (from so in db.SalesOrderDetails
                    where  ItemDescription.Contains(ItemDescription)
                            select new { so.TransNo }).AsEnumerable();


listreceipt = listreceipt.Where(p => filterTransNos.Any(p2 => p2.TransNo == p.TransNo)).ToList();


답변

HashSet을 사용하여 수행하는 방법은 다음과 같습니다.

        HashSet<String> hs = new HashSet<string>(new String[] { "Pluto", "Earth", "Neptune" });
        String[] arr =
        {
            "Pluto",
            "Earth",
            "Neptune",
            "Jupiter",
            "Saturn",
            "Mercury",
            "Pluto",
            "Earth",
            "Neptune",
            "Jupiter",
            "Saturn",
            "Mercury",
            // etc.
        };
        ICollection<String> coll = arr;

        String[] arrStrFiltered = coll.Where(str => hs.Contains(str)).ToArray();

HashSet은 기본적으로 거의 O (1)이므로 복잡성은 O (n)으로 유지됩니다.


답변