2016-09-03 2 views
1

내 응용 프로그램의 경우 Item 유형에 따라 정적 사전 값으로 내 Item 엔티티를 정렬하려고합니다. 상관없이 항상라는 오류지고, 난 그냥 작동 할 수 없습니다 무엇을하려고 :정적 사전 값으로 linq 쿼리 정렬

유형의 상수 값을 만들 수 없습니다 'System.Collections.Generic.KeyValuePair`2는 [[MyApp.Models합니다. 항목 + ItemTypeE, MyApp, 버전 = 1.0.0.0, 문화 = 중립, PublicKeyToken = null], [System.Int32, mscorlib, 버전 = 4.0.0.0, 문화 = 중립, PublicKeyToken = b77a5c561934e089] '.

private IOrderedQueryable<Item> Sort(IQueryable<Item> items) 
{ 
    return items.OrderBy(i => i.Type) 
       .ThenBy(i => 
        Item.MyDic.Keys.Any(key => key == i.Type) 
        ? Item.MyDic[i.Type].Item2 
        : -1); 
} 

그리고 Item 클래스 :

public partial class Item : CavalenaEntity, ICavalenaEntity 
{ 
    public enum ItemTypeE 
    { 
     Type1 = 0, 
     Type2 = 1, 
     ... 
    } 

    public static Dictionary<ItemTypeE, Tuple<int, int>> MyDic = new Dictionary<ItemTypeE, Tuple<int, int>>() 
    { 
     { ItemTypeE.Type1, new Tuple<int, int>(0, 1) }, 
     { ItemTypeE.Type2, new Tuple<int, int>(1, 100) }, 
     ... 
    } 
} 

Item.MyDic.Keys.Any(key => key == i.Type)입니다 만 유형 또는 열거 형 원시적이 컨텍스트 여기

에서 지원됩니다 내 저장소 방법은 Item 개체를 정렬하는 데 노력하고있다 잘 작동하지만 Item.MyDic[i.Type].Item2과 같은 것을 얻을 수있는 방법을 찾을 수 없습니다. 새 익명 개체로 KeyValuePair을 선택하려고했으나 selectMany을 사용해 보았지만 여전히 작동하지 않습니다.

누군가 내게 그러한 쿼리를 달성하는 방법을 보여줄 수 있다면 정말 감사 할 것입니다. 고마워요.

최종 솔루션

public IPagedList<Item> GetSoldableItems(Item.SortableTypeE sortName, SortOrder.TypeE sortOrder, int pageNb) 
    { 
     var items = entities.Items.Where(i => ...); 

     var orderedItems = Sort(items.AsEnumerable(), sortName, sortOrder).ToList(); 

     return orderedItems.ToPagedList(pageNb, 10); 
    } 

    private IOrderedEnumerable<Item> Sort(IEnumerable<Item> items, Item.SortableTypeE sortName, SortOrder.TypeE sortOrder) 
    { 
     IOrderedEnumerable<Item> result = null; 

     switch(sortName) 
     { 
      case Item.SortableTypeE.Type: 
       result = sortOrder == SortOrder.TypeE.ASC 
        ? items.OrderBy(i => i.Type) 
        : items.OrderByDescending(i => i.Type); 
       result = result.ThenBy(i => 
         Item.MyDisc.ContainsKey(i.Type) 
         ? Item.MyDisc[i.Type].Item2 
         : -1) 
        .ThenByDescending(i => i.Bonus); 
       break; 
      ... 
      default: break; 
     } 

     return result; 
    } 

답변

1

문제는 공급자가 SQL로 쿼리를 번역하려고하고 로컬 메모리 사전을 사용하고 있기 때문에 그렇게하는 데 실패한다는 것입니다 당신의 정렬 논리. 그 해결책은 데이터를 드래그하여 메모리 내에서 정렬하는 것입니다. 다른 경우에 대한

private IEnumerable<Item> Sort(IQueryable<Item> items) 
{ 
    return items.AsEnumerable().OrderBy(i => i.Type) 
           .ThenBy(i => Item.MyDic.Keys.Any(key => key == i.Type) 
              ? Item.MyDic[i.Type].Item2: -1); 
} 

참고 : 더 필터링이 여기가 없기 때문에,이 성능 측면에서 괜찮을 것, 그 후 필터링 논리가있을 때 AsEnumerable()을 사용하지 않는 당신이 필터링되지 않을 것입니다 그런 식으로하기 때문에 서버 측.

+0

답변 해 주셔서 감사합니다. 그러나 모든 것은 사실 꽤 크며, 많은 기준을 매개 변수로 사용하고 정렬 열과 정렬 순서를 정렬합니다. 내가 게시 한'sort' 메서드는 실제로 필터링 직후에 호출되며 정렬 열과 순서에 따라 달라집니다. 문제가 사전 가치를 얻는 것에 불과하기 때문에 중요하지 않다고 생각하여 게시물을 단순화했습니다. 또한,'Item' 테이블은 많은 행을 가질 수 있습니다. AsEnumerable()을 사용하는 것이 여전히 괜찮습니까? 다른 방법이 있습니까? –

+1

@Flash_Back 이전에 필터링 했으므로 성능에 미치는 영향은 없습니다. 다른 방법으로는, 그렇다. SQL 번역 된 Linq 쿼리에서 로컬 사전을 사용할 수 없습니다. 이것에 대해 생각해보십시오.이 쿼리는 순수한 SQL로 변환되어야합니다. 사용자 지정 유형 및 튜플을 사용하는 로컬 키 - 값 쌍 사전이있을 때 공급자가 어떻게 할 수 있습니까? 서버 측에서 모든 것을 실행해야한다면, 스토어드 프로 시저를 작성하고 Linq를 사용하여 호출 한 다음 결과를 오브젝트에 맵핑하십시오. 그러나 이것은이 답변의 범위를 벗어납니다. – user3185569

+0

나는 실제로 공연에 대해 두려워했지만, 확실히 말하면, 필터링이 이루어지기 때문에 어떤 문제도 없어야합니다.귀하의 설명에 대해 고맙습니다. 지금은 더 잘 이해하고 있습니다.) –