web-dev-qa-db-ja.com

DbSet <T>をList <T>にキャストする方法

次の簡略化されたEntity Framework 6のコンテキストを考えると、エンティティをリストに入力しようとしていますが、リフレクションを介してキャストする方法(問題だと思います)に問題があります。

public class FooContext : DbContext
{
   public virtual IDbSet<FooClass> Foo { get; set; }    
   //...
}

public class FooClass
{
    public int Id{ get; set; }
    public string Name {get; set; }
    //...    
}

public main()
{
     using (var context = new FooContext())
     {
         var sets = typeof(FooContext).GetProperties().Where(pi => pi.PropertyType.IsInterface && pi.PropertyType.GetGenericTypeDefinition().ToString().ToLower().Contains("idbset"));

         foreach (var set in sets)
         {
             //When I debug and enumerate over 'value' the entire results are shown so I believe the reflection part is OK.
             var value = set.GetValue(context, null);

             //Always returns null. How can I cast DbSet<T> to List<object> or List<T>? 
             var list = value as List<object>();

             //...
         }
     }
}

私が行っているいくつかの統合テストのユーティリティメソッドでこれを行っています。 (SqlConnectionやSqlCommandなどを使用して)直接インラインSQL呼び出しを使用せずにこれを実行しようとしています(データストアがOracleなどに変更される可能性があるため)。

11
Kyle

IDBSetは_IQueryable<TEntity>_、_IEnumerable<TEntity>_、IQueryable、およびIEnumerableを継承するため、この方法で直接リストにキャストすることはできません。 .ToList()または.ToListAsync()を使用すると、DBSet内のすべてのエンティティの_List<TEntity>_を取得できます

ただし、THisはメモリ内のすべてのエンティティのコピーを作成するため、DBSetでLINQを直接操作することを検討する必要があります。

12
LInsoDeTeh
//dont forget using System.Linq;
using (var context = new FooContext())
{
   IQueryable<FooClass> rtn = from temp  in context.Foo select temp;
   var list = rtn.ToList();
}
10
VicYam

VicYamの回答に加えて、詳細な説明がある簡単な方法を以下に示します。

System.Linq名前空間を追加すると、IQueryableを取得してListに変換する必要がなくなります。代わりに、DbSetオブジェクトの拡張メソッドを取得します。

これは何を意味するのでしょうか? DbSetを継承しているため、IEnumerableを単独で返すことができます。コンシューマは、おそらく開発者であり、.ToListまたはその他の必要なリストの種類を実行できます。

最も簡単

これは、DbSetをそのまま返します。これは、IEnumerableに変換できるリスト型であるListから既に継承しています。

List<ObjectType> list = new List<ObjectType>();
using (var context = new FooContext())
{
    list = context.Foo;
}

代替

IEnumerableからListにすぐに変換できます。

using (var context = new FooContext())
{
    var list = context.Foo.ToList();
}

まだVicYamの回答が必要ですが、1行で入力しますか?

using (var context = new FooContext())
{
    var list = context.Foo.AsQueryable().ToList();
}
3
AzzamAziz

キャストできません。 DbSetから非同期で、または単に同期的にToListAsync<T>()を列挙して、ToList()を介してIQueryableから新しい_List<T>_を作成するだけです

また、私はあなたのシナリオのための具体的な実現を作成する方が良いと思います。 EF用に作成します。たとえば、NHibernateの使用を開始するときは、NHibernateのテストなどを作成します。将来のサポートではより単純になり、一般的なものを作成しようとしますが、修正とデバッグはより複雑になります。

参考までに、これらの統合テストが必要ですか?マッピング/実装がデータベースで機能していることをテストする方が良いでしょう。もっと重要な部分になると思います。もちろん、以前にやったことがなければ。

1
ivamax9
private StudentDatabaseEntities db = new StudentDatabaseEntities();

public List<StudentDatabaseDbTableModel> AllProducts()
{
    return db.StudentDatabaseDbTableModel.ToList();
}   

db.StudentDatabaseDbTableModelはDbSetタイプです。 ToListは、DbSetクラス内のメソッドです。 ToListメソッドは、タイプDbSetのオブジェクトをリストタイプに変換します。

0
Siddarth Kanted