2016-04-26 8 views
-1

私はasp.net mvcサイトを持っており、モデルに必要なときに計算されるフィールドをソートすることができません。データベース内に格納されていないフィールドでソートする方法

private decimal _total = -1; 
    public decimal Total 
    { 
     get 
     { 
      if (_total < 0) 
      { 
       _total = get_total(TableId); 
      } 
      return _total; 
     } 
    } 

    private decimal get_total(int id) 
    { 
     ....Many Calcs 
    } 

私は合計でソートしようとしているが、私はエラーを取得:

追加情報:指定されたタイプのメンバーの合計を「エンティティへのLINQでサポートされていません。初期化子、エンティティメンバー、エンティティナビゲーションプロパティのみがサポートされています。

は、ここに私のActionLinkのです:

@Html.ActionLink("By Total", "Index", new { sortOrder = ViewBag.Total, currentFilter = ViewBag.CurrentFilter }, new { @class = "btn btn-danger" }) 

私はいくつかの同様の問題を発見したが、私はどれだけこれでソートするかを把握することはできません。

そして私のコントローラ。私はこれを明確にするために編集しようとしました。

public ActionResult Index(string sortOrder) 
    { 

     ViewBag.CurrentSort = sortOrder; 
     ViewBag.Total = sortOrder == "total" ? "total_desc" : "total"; 

     var records = from u in db.Records.Include(t => t.User).Where(t => t.Active == true) 
        select u; 

     switch (sortOrder) 
     { 
      case "total": 
       records = db.Records.OrderBy(u => u.Total).Where(t => t.Active == true); 
       break; 
      case "rating_desc": 
       records = db.Records.OrderByDescending(u => u.Total).Where(t => t.Active == true); 
       break; 
      default: 
       records = db.Records.OrderBy(u => u.Title).Where(t => t.Active == true); 
       break; 
     } 

     return View(records.ToList()); 
    } 
+0

は、データを並べ替えるクエリを表示します。 –

+0

実際にソートした場所、またはこの 'Total'プロパティを追加した場所のコードは表示されません。物事の見た目からは、部分クラスを介してEFエンティティに追加したと思います。 –

+0

ごめんなさい –

答えて

3

が、これはSQLの文に変換することができないよう、このプロパティで注文しようとする前にToList()メソッドを呼び出すようにしてください。

// I assume currently your query is something like this 
DbContext.SomeEntity.Where(...).OrderBy(e => e.Total); 

// After calling .ToList() you can sort your data in the memory (instead of in db) 
DbContext.SomeEntity.Where(...).ToList().OrderBy(e => e.Total); 

UPDATE:このためrecords変数の型の

var records = from u in db.Records.Include(t => t.User).Where(t => t.Active == true) select u; 

System.Linq.IQueryable<Project.Models.Record>になり、それが理由である:
問題は、まずあなたがこの行でrecords変数を宣言することです.AsQueryable()でキャストするために必要なスイッチケース。

さらに、初期値は常にswitch文でオーバーライドされるため、現時点では初期化する必要はありません。あなたは何をすべき

public ActionResult Index(string sortOrder) 
{ 
    /* ViewBag things */ 

    IEnumerable<Record> records = 
     db 
      .Records 
      .Include(record => record.User) 
      .Where(record => record.Active) 
      .ToList(); // At this point read data from db into memory 

    // Total property cannot be translated into an SQL statement. 
    // That's why we call it on memory objects instead of DB entities. 
    switch (sortOrder) 
    { 
     case "total": 
      records = records.OrderBy(record => record.Total); 
      break; 

     case "rating_desc": 
      records = records.OrderByDescending(record => record.Total); 
      break; 

     default: 
      records = records.OrderBy(record => record.Title); 
      break; 
    } 

    return View(records.ToList()); 
} 
+0

質問を変更した後、次のエラーが表示されます。エラー 'System.Linq.IOrderedEnumerable 'の型を暗黙的に 'System.Linq.IQueryable '。明示的な変換が存在します(キャストがありませんか?) –

+0

あなたの変換の問題に関する私の答えに更新が追加されました。 – Gabor

+0

Gaborさんに感謝します。各switch文をキャストする必要を回避する上で唯一本当のメリットはありますか?私はちょうど遅れたローディングをすぐに実装することを望んでいるので好奇心が強いですし、それはienumerableでサポートされていないと信じていますが、再びそれをキャストして - 私は同じことをやっています - 私はC#で初めてです。 –

0

私はIQueryableをとして私のクエリをキャストするのに必要なので、ここで更新スイッチです:

switch (sortOrder) 
{ 
    case "total": 
     records = db.Records.Where(t => t.Active == true).AsQueryable().OrderBy(u => u.Total)); 
     break; 
    case "rating_desc": 
     records = db.Records.Where(t => t.Active == true).AsQueryable.OrderByDescending(u => u.Total).; 
     break; 
    default: 
     records = db.Records.Where(t => t.Active == true).AsQueryable.OrderBy(u => u.Title).; 
     break; 
} 
+0

あなたの変換の問題に関する私の答えに更新が追加されました。あなたは私の更新された答えに記載されているようにキャストする必要はありませんでした。 – Gabor

関連する問題