linq를 사용하여 ID 목록을 기반으로 여러 레코드 선택
내 UserProfile
테이블 의 ID가 포함 된 목록이 있습니다. 어떻게 내가 모두를 선택할 수 있습니다. UserProfiles
나는에있어 아이디의 목록을 기반으로 var
사용 LINQ
합니까?
var idList = new int[1, 2, 3, 4, 5];
var userProfiles = _dataContext.UserProfile.Where(......);
바로 여기에 생겼습니다. for 루프 등을 사용 하여이 작업을 수행 할 수 있습니다.하지만 LINQ
.
그것을 위해 사용할 수 있습니다 . 실제로 절 을 생성하려고 할 때 약간 거꾸로 느껴지 지만 이렇게해야합니다.Contains()
IN
var userProfiles = _dataContext.UserProfile
.Where(t => idList.Contains(t.Id));
또한 각 UserProfile
레코드에 int
Id
필드 가 존재 가정 합니다. 일치하는 경우 그에 따라 조정해야합니다.
.Where .Contains를 및 솔루션은 O (N 제곱)의 결과를 가공합니다. Simple .Join은 훨씬 더 나은 성능을 가져옵니다 (해싱으로 인해 O (N)에 가까움). 따라서 올바른 코드는 다음과 가변적입니다.
_dataContext.UserProfile.Join(idList, up => up.ID, id => id, (up, id) => up);
그리고 이제 측정 결과입니다. 100,000 개의 UserProfile과 100,000 개의 ID가 생성되었습니다. Join은 32ms, .Where with .Contains는 2 분 19 초가 걸렸습니다! 이 테스트에서 내 전시를 증명하기 위해 순수 IEnumerable을 사용했습니다. IEnumerable 대신 List를 사용하면 .Where 및 .Contains가 더 빠 사용합니다. 어쨌든 그 차이는 중요합니다. 가장 빠른 .Where .Contains는 Set <>입니다. 모든 것은 .Contains에 대한 기본 콜레 션의 모든 것이 달려 있습니다. 봐이 게시물 아래 에있는 내 테스트 샘플에 복잡성. LINQ에서 배울 수 있습니다.
private static void Main(string[] args)
{
var userProfiles = GenerateUserProfiles();
var idList = GenerateIds();
var stopWatch = new Stopwatch();
stopWatch.Start();
userProfiles.Join(idList, up => up.ID, id => id, (up, id) => up).ToArray();
Console.WriteLine("Elapsed .Join time: {0}", stopWatch.Elapsed);
stopWatch.Restart();
userProfiles.Where(up => idList.Contains(up.ID)).ToArray();
Console.WriteLine("Elapsed .Where .Contains time: {0}", stopWatch.Elapsed);
Console.ReadLine();
}
private static IEnumerable<int> GenerateIds()
{
// var result = new List<int>();
for (int i = 100000; i > 0; i--)
{
yield return i;
}
}
private static IEnumerable<UserProfile> GenerateUserProfiles()
{
for (int i = 0; i < 100000; i++)
{
yield return new UserProfile {ID = i};
}
}
콘솔 출력 :
경과. 가입 시간 : 00 : 00 : 00.0322546
경과. 어디. 시간 포함 : 00 : 02 : 19.4072107
좋은 대답이 중요한 한 가지를 잊지 않고 . 다른 결과를 제공합니다!
var idList = new int[1, 2, 2, 2, 2]; // same user is selected 4 times
var userProfiles = _dataContext.UserProfile.Where(e => idList.Contains(e)).ToList();
이것은 DB에서 2 개의 행을 반환 할 것입니다 (사용자의 고유 한 정렬 목록을 원하는 경우입니다).
그러나 대부분의 경우 정렬되지 않은 결과 목록을 원할 수 있습니다. 항상 SQL 쿼리에 대해 생각해야합니다. 진행 상황을 비용으로 eshop 쇼핑 카트의 예를 참조하십시오.
var priceListIDs = new int[1, 2, 2, 2, 2]; // user has bought 4 times item ID 2
var shoppingCart = _dataContext.ShoppingCart
.Join(priceListIDs, sc => sc.PriceListID, pli => pli, (sc, pli) => sc)
.ToList();
그러면 DB에서 5 개의 결과 가 반환 됩니다. 이 경우 'contains'를 사용하는 것은 잘못된 것입니다.
간단해야합니다. 이 시도 :
var idList = new int[1, 2, 3, 4, 5];
var userProfiles = _dataContext.UserProfile.Where(e => idList.Contains(e));
참고 URL : https://stackoverflow.com/questions/16824510/select-multiple-records-based-on-list-of-ids-with-linq
'IT' 카테고리의 다른 글
Android Lollipop 내비게이션 바 색상 변경 (0) | 2020.08.11 |
---|---|
빈 필드에 대해 SOLR을 쿼리하는 방법은 무엇입니까? (0) | 2020.08.11 |
하위 문자열 특정 문자 가져 오기 이전의 모든 것 (0) | 2020.08.11 |
jQuery는 줄 바꿈을 br로 변환 (nl2br 상당) (0) | 2020.08.11 |
여러 필드로 개체 배열을 정렬하는 방법은 무엇입니까? (0) | 2020.08.11 |