2017-01-27 9 views
2

SQLデータベースからテーブルを読み込むようにEntity Frameworkクラスを設定していますが、LINQ式を渡して特定のオブジェクトのみをフィルタする方法を理解できません。私は式ツリーを構築し、クラス内から動的にこれを行う方法があることを知っていますが、これを行うための最良の方法を考えることはできません。LINQ式をパラメータとして渡す

ご了承ください。

class Customer 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

class MyObjectCollection<T> where T : class 
{ 
    private List<T> myInternalCollection = new List<T>(); 

    MyObjectCollection() 
    { 
     using (var db = new MyContext()) 
     { 
      foreach (T row in db.Set<T>()) 
      { 
       // Enumerate the data, do whatever with it... 
       myInternalCollection.Add(row); 
      } 
     } 
    } 

    MyObjectCollection(var MyLinqExpression) 
    { 
     using (var db = new MyContext()) 
     { 
      foreach (T row in db.Set<T>().Where.MyLinqExpression() 
      { 
       // Enumerate the data, do whatever with it... 
       myInternalCollection.Add(row); 
      } 
     } 
    } 
} 

// Works fine: 
MyObjectCollection<Customer> allCustomers = new MyObjectCollection<Customer>(); 

// Would like something like this: 
MyObjectCollection<Customer> customersP = new MyObjectCollection<Customer>(c => c.StartsWith("P")); 
+0

パラメータ '述語'として試してみてください。 – Abion47

+2

'Queryable.Where'メソッドのシグネチャを見てください(基本的には何を求めているのでしょうか)。ヒント: 'Expression >' –

答えて

2

方法は、Tは、あなたがあなたのどこ方法を適用するdbSetオブジェクト型になりFunc<T, bool>のパラメータを取りLINQの。

だからあなたのコードを動作させるために、あなたはこれを行うことができます。

public MyObjectCollection(Func<T, bool> MyLinqExpression) 
{ 
    using (var db = new MyContext()) 
    { 
     foreach (T row in db.Set<T>().Where(MyLinqExpression)) 
     { 
      // Enumerate the data, do whatever with it... 
      myInternalCollection.Add(row); 
     } 
    } 
} 

UPDATE: また、あなたは一般的なコレクションを探し、代わりのプライベートリストをカプセル化された機能を達成するためにオブジェクト、あなたは私が下に示すようにリストから継承することができます。したがって、MyObjectCollectionをListのように機能させたい場合は、以下に示すようにすることができます。

だから、上からあなたのコードで、あなたがこれに変更することができます。

public class MyObjectCollection<T> : List<T> where T : class 
{ 
    public MyObjectCollection() 
    { 
     using (var db = new MyContext()) 
     { 
      foreach (T row in db.Set<T>()) 
      { 
       // Enumerate the data, do whatever with it... 
       this.Add(row); 
      } 
     } 
    } 

    public MyObjectCollection(Func<T, bool> MyLinqExpression) 
    { 
     using (var db = new MyContext()) 
     { 
      foreach (T row in db.Set<T>().Where(MyLinqExpression)) 
      { 
       // Enumerate the data, do whatever with it... 
       this.Add(row); 
      } 
     } 
    } 
} 
+0

この例では、戻り値の型が 'bool'の場合、' Func'に 'Predicate'を使用することをお勧めします。 – Abion47

+1

@ Abion47どこのメソッドでも常にFuncを使いました。私はPredicateがうまくいくと思うが、 'Func 'はWhereメソッドがどのように実装されているのか、これらのタイプのメソッドFuncのために.NET 3.5がPredicateよりも推奨されているからだ。ここではトピックのニーススタックポストがあります - Jon SkeetとMarc Gravellの両方がこのトピックの重点を置いています。http://stackoverflow.com/questions/665494/why-funct-bool-instead-of-predicatet – JustSomeDude

+2

私はこの例では、継承が集約よりも優れているかどうかはわかりません。継承することで、他の人がmyInternalCollectionを変更できるようになります。これは、クラスが前述のように機能するためには必要ないようです。そうしないと、myInternalCollectionはprivateに定義されません。この継承を使用することに加えて、myInternalCollectionをたとえばDictionaryに、または他のアイテムのコレクションに変更する可能性が制限されます。助言:クラスの使用が –

関連する問題