2011-11-08 7 views
2

나는 사용자의 바구니에 저장 한 productID를 통과하는 간단한 foreach 루프를 가지고 있으며 데이터베이스에서 제품의 세부 사항을 조회합니다.루프 내에서 IQueryable을 추가하는 방법

내 코드에서 알 수 있듯이 현재 루프에서 변수를 덮어 쓸 때 화면의 마지막 항목이 반환됩니다. 나는 바구니에있는 품목에 대한 제품 세부 사항을 표시 할 수 있도록이 연결을 할 수 있어야합니다.

나는 내가 사용하는 리피터에만 ProductID를 저장하는 것과 같이 매우 쉬운 작업을 할 수 있다는 것을 알고 있으며 데이터베이스를 호출하기 위해 onitemdatabound하지만 가능한 한 데이터베이스 호출을하고 싶습니다.

현재 나는 다음 (제거 복잡한 예에서 조인하지만,이 문제가 허락한다면 나) 알고있다 : 당신의 도움에 대한

IQueryable productsInBasket = null; 
    foreach (var thisproduct in store.BasketItems) 
    { 
     productsInBasket = (from p in db.Products 
           where p.Active == true && p.ProductID == thisproduct.ProductID 
           select new 
           { 
            p.ProductID, 
            p.ProductName, 
            p.BriefDescription, 
            p.Details, 
            p.ProductCode, 
            p.Barcode, 
            p.Price 
           }); 
    } 

    BasketItems.DataSource = productsInBasket; 
    BasketItems.DataBind(); 

감사합니다! 당신이 정말 같은 것을 원하는처럼

답변

7

그것은 소리 : 당신이 그것에 ToList()를 호출하기 때문에 잘 작동 존의 대답에

var productIds = store.BasketItems.Select(x => x.ProductID).ToList(); 
var query = from p in db.Products 
      where p.Active && productIds.Contains(p.ProductID) 
      select new 
      { 
       p.ProductID, 
       p.ProductName, 
       p.BriefDescription, 
       p.Details, 
       p.ProductCode, 
       p.Barcode, 
       p.Price 
      }; 
+0

안녕 존, 고마워. 그것은 대접을했습니다! 나는 전에 그런 필터를 사용하는 것을 결코 생각하지 못했습니다. 알아야 할 핸디 :) –

0

을의 된 IQueryable는 그러나,는 IEnumerable로 변환됩니다. 그러면 쿼리가 실행되고 응답이 검색됩니다. 상황에 따라 바스켓 용 제품을 검색하려는 경우와 제품 수가 상당히 적기 때문에 문제가되지 않을 수 있습니다.

그러나 나는 비슷한 상황에 직면 해 있습니다. 여기서 나는 회원을위한 친구를 찾고 싶습니다. 우정은 두 명의 회원이 속한 그룹에 달려 있습니다. 적어도 한 그룹을 공유하면 친구가됩니다. 따라서 특정 구성원에 대한 모든 그룹의 모든 구성원을 검색 한 다음 해당 구성원에서 모든 구성원을 검색해야합니다.

내 경우에는 ToList 방식을 적용하지 않습니다. ToList 방식은 다양한 방식으로 친구를 처리 할 때마다 쿼리를 실행하기 때문에 내 경우에는 적용 할 수 없습니다. 우리가 공유 할 수있는 물건을 찾으십시오. 데이터베이스에서 모든 구성원을 검색하여 쿼리를 작성하고 마지막으로 가능한 한 실행하면 성능이 저하됩니다.

그래도이 첫 번째 시도는 내가 속한 모든 그룹 (IQueryable)을 검색하고 목록 결과 (IEnumerable)를 초기화 한 다음 모든 그룹을 반복하고 모든 구성원을 결과에 추가합니다 아직 목록에 없다. 마지막으로, 내 인터페이스가 IQueryable이 반환되도록 강제 한 이후 AsIQueryable로 목록을 반환했습니다.

이것은 코드의 불쾌한 조각 이었지만 적어도 효과가있었습니다. 나는 목록에 모든 공유 멤버를 추가하기 때문에, 그럼 그냥 내 게시물의 조건을 만족하는 된 IQueryable에 목록을 변환

var result = new List<Member>(); 
foreach (var group in GetGroupsForMember(member)) 
    result.AddRange(group.GroupMembers.Where(x => x.MemberId != member.Id && !result.Contains(x.Member)).Select(groupMember => groupMember.Member)); 
return result.AsQueryable(); 

그러나,이, 나쁜 : 그것은 같은 것을 보았다. 데이터베이스에서 영향을받는 모든 구성원을 검색 할 것입니다.

페이지 매김 목록을 상상해보십시오. 그러면이 목록에서 특정 범위를 골라 내고 싶을 것입니다. 이 작업이 IQueryable로 완료되면 쿼리가 페이지 매김 문으로 완료됩니다. 이 작업이 IEnumerable로 완료되면 쿼리가 이미 실행되고 모든 작업이 메모리 내 결과에 적용됩니다.

(여러분도 알다시피, 엔티티의 관계 (GroupMember => Member)를 탐색하므로 커플 링이 증가하면 모든 종류의 불쾌한 상황이 계속 발생할 수 있습니다.나는이 행동을 제거하기를 원했다).

그래서, 오늘 밤, 나는 또 다른 라운드를했고 나는이 같은 데이터를 선택 훨씬 간단한 방법으로 결국 :

var groups = GetGroupsForMember(member); 
var groupMembers = GetGroupMembersForGroups(groups); 
var memberIds = groupMembers.Select(x => x.MemberId); 
var members = memberService.GetMembers(memberIds); 

두 얻을 방법이 된 IQueryable 명예 결코 목록으로 변환하거나 다른 IEnumerable. 세 번째 줄은 IEnumerable의 LINQ 쿼리 ontop을 수행합니다. 마지막 줄은 멤버 ID를 가져오고 IQueryables와 독점적으로 작동하는 다른 서비스의 모든 멤버를 검색합니다.

이것은 성능면에서 여전히 끔찍할 수 있지만 필요에 따라 나중에 더 최적화 할 수 있습니다. 적어도 필자는 불필요한 데이터로드를 피합니다.

여기 내가 끔찍한 잘못인지 알려주세요.

관련 문제