4

私はグリッドビューを持っています。そのデータソースは次の関数です:

public static List<Train> GetTrainsByIDs(int [] ids) {
    using (var context = new MyEntities()) 
    {
        return ids.Select(x => context.Trains.Single(y => y.TrainID ==x)).AsQueryable().Include(x=>x.Station).ToList();
    }
}

グリッド ビューには の ItemTemplate があり<%# Eval("Station.Name") %>ます。The ObjectContext instance has been disposed and can no longer be used for operations that require a connectioninclude メソッドを使用したにもかかわらず、これによりエラーが発生します。

関数を次のように変更すると

public static List<Train> GetTrainsByIDs(int [] ids) {
    using (var context = new MyEntities()) 
    {
        return context.Trains.Where(x => ids.Contains(x.TrainID)).Include(x=>x.Station).ToList();
    }
}

それは正常に動作しますが、それらは間違った順序で出てきます。また、2 つの同じ ID がある場合、リストに 2 つの同一の列車が必要です。

新しいビューモデルを作成する以外にできることはありますか? 助けてくれてありがとう

4

2 に答える 2

1

最初のクエリについては、遅延実行です。of を作成しましたIEnumerableTrain、メソッドがないことに気付いたIncludeので、にキャストしIQueryable、Include を追加し、ToList()遅延読み込みを防ぐために を追加しました。

しかし、 DbExtensions.Include の MSDN によると:

この拡張メソッドは、IQueryable ソース オブジェクトの Include(String) メソッドが存在する場合、そのメソッドを呼び出します。ソース IQueryable に一致するメソッドがない場合、このメソッドは何もしません。

(私のものを強調)

選択の結果は にIEnumerable変換されますがIQueryable、現在は実装されEnumerableQueryていませんInclude。そして、何も起こりません。

ここで、データがグリッドに入り、ステーションを表示しようとします。これにより、コンテキストがなくなっている間に遅延読み込みがトリガーされます。

それとは別に、この設計には別の欠陥があります: ID ごとに個別にクエリを起動します。

したがって、2 番目のクエリの方がはるかに優れています。sを含めて 1 つのクエリStationです。しかし今では、データベースが喜んで返す順序によって順序が決定されます。Concatこれを解決するために使用できます:

IQueryable<Train> qbase = context.Trains.Include(x=>x.Station);
IQueryable<Train> q = null;

foreach (var id in ids)
{
  var id1 = id; // Prevent modified closure.
  if (q == null)
    q = qbase.Where(t => t.Id == id1);
  else
    q = q.Concat(qbase.Where (t => t.Id == id1));
}

生成されたクエリは (控えめに言っても) あまり洗練されたものではありませんが、結局のところ、多くのクエリではなく 1 つのクエリです。

于 2012-09-02T21:55:03.063 に答える
0

@Gert Arnold の回答を読み、2 段階で実行するというアイデアを得た後、次のような最初のクエリを使用して非常に簡単に管理しました。

using (context = new MyEntities())
{
    var trns = context.Trains.Include(x => x.Station);
    return ids.Select(x => trns.Single(y => y.TrainID == x)).ToList();
}
于 2012-09-05T18:10:42.507 に答える