2017-01-07 5 views
3

選択したプロパティで並べ替えオブジェクトを実装したいと考えています。私はToListメソッドメソッドによって、クエリを実体化するとLINQで選択したプロパティでオブジェクトを並べ替える

  Expression<Func<Goal, object>> sortProperty; 

      switch (sc.Sort) 
      { 
       case "Name": 
        sortProperty = p => p.Name; // String 
        break; 
       case "Priority": 
        sortProperty = p => p.Priority; // Enum 
        break; 

       case "CreatedDate": 
        sortProperty = p => p.CreatedDate; // DateTime 
        break; 

       case "Id": 
       default: 
        sortProperty = p => p.Id; // Long 
        break; 
      } 

      queryable = sc.IsAscending 
       ? queryable.OrderBy(sortProperty) 
       : queryable.OrderByDescending(sortProperty); 

私は( 'ID' シナリオでは)例外を取得:

追加情報: 「システムを入力するタイプ 'System.Int64' をキャストすることができません。オブジェクト '。エンティティへのLINQは、キャストEDMプリミティブ または列挙型のみをサポートします。

私の質問はこうです:このような方法で機能を実装することは可能ですか?あるいは、私はOrderByとOrderByDescendingのどちらかを選択するように移動する必要がありますか?

+0

あなたは '(オブジェクト)' 'たSortProperty = P =>(オブジェクト)p.Idにキャストすることが必要な理由。 // Long'? 'sortProperty = p => p.Id;'の何が問題なのですか? –

+0

@EugenePodskal:これは私の最初の考えでしたが、 'sortProperty'は' Expression >型です。これはキャストなしで広く同じ苦情があると思われます。正確な苦情)。 – Chris

+0

この(オブジェクト)キャストは私のテストのものです。私はコードから削除します – Jacek

答えて

1

これはボクシングのために発生します。 stringからobjectへの変換は、EFがそれを見る前に削除されていないので、名前でソートすると機能します。 longobjectに変換するのはかなり大変です。そのため、式ツリーに保存されていて、EFが混乱してしまいます。

この場合、Expression<Func<Goal, long>>を使用する方法を見つける必要があります。ヘルパーメソッドはおそらくコードの重複を避けるための最も簡単な方法です。

abstract class Orderer { 
    public abstract IQueryable<Goal> Order(IQueryable<Goal> queryable); 
} 

class Orderer<T> : Orderer { 
    private readonly Expression<Func<Goal, T>> _property; 
    public Orderer(Expression<Func<Goal, T>> property) { 
     _property = property; 
    } 
    public override IQueryable<Goal> Order(IQueryable<Goal> queryable) { 
     return queryable.OrderBy(_property); 
    } 
    public override IQueryable<Goal> OrderDescending(IQueryable<Goal> queryable) { 
     return queryable.OrderByDescending(_property); 
    } 
} 

Orderer makeOrderer<T>(Expression<Func<Goal, T>> property) { 
    return new Orderer(property); 
} 

、その後

Orderer orderer; 
switch (sc.Sort) 
{ 
    case "Name": 
     orderer = makeOrderer(p => p.Name); 
     break; 
    // ... 
} 
queryable = sc.IsAscending 
    ? orderer.Order(queryable) 
    : orderer.OrderDescending(queryable); 
関連する問題