2017-04-05 3 views
0

データソースを取得するデータベースコンテキストがあります。Entity Frameworkクエリデコレータがすぐにクエリを送信します

public class EFDataSource : DbContext 
{ 
    public IDbSet<Product> Products { get; set; } 
} 

私は、製品のコード側に非常に多くのクエリ基準を持っています。

var data = new EFDataSource().Products 
       .Where(criteria1) 
       .Where(criteria1) 
       .Where(...) 

このクエリロジックをクラスで分割する必要があります。

var query1 = new Query(); // Sends to database 
var query2 = new FilterByUser(query1,"username");  // Sends to database 
if(somethingHappened) 
    var query3 = new FilterBySomething(query2); // Sends to database 


public class Query : IQuery<Product> 
{ 
    public IQueryable<Product> Data 
    { 
     get { return new EFDataSource().Products; } 
    } 
} 

public class FilterByUser: IQuery<Product> 
{ 
    private readonly string username; 
    private readonly IQuery<Product> query; 

    public FilterByUser(IQuery<Product> query, string username) 
    { 
     this.username = username; 
     this.query = query; 
    } 

    public IQueryable<Product> Data 
    { 
     get { return query.Data.Where(s => s.CreatedBy == username); } 
    } 
} 

ただし、これらのすべての手順でデータベースにクエリが送信されます。しかし、私は1つだけのクエリを送信したい。

+0

あなたのフィルタメソッド内のコードは何ですか? –

+0

投稿を更新しました – barteloma

+0

デバッガ体験のようなサウンドです。 'IQueryable 'を実行しないと(評価すると、いくつかのデバッガウィンドウで列挙型を展開する)データベースに送られる方法はありません。 –

答えて

0

これは動作します。キーは、db呼び出しの結果を変数に格納することです。この変数は、「キャッシュ」などの好きなものを呼び出すことができます。

データベース:

CREATE TABLE [dbo].[Product](
    [Id] [int] IDENTITY(1,1) NOT NULL, 
    [username] [varchar](20) NULL, 
    [username2] [varchar](20) NULL, 
    [username3] [varchar](20) NULL, 
    [CreatedBy] [varchar](20) NULL 
) ON [PRIMARY] 

GO 
SET ANSI_PADDING OFF 
GO 
SET IDENTITY_INSERT [dbo].[Product] ON 

INSERT [dbo].[Product] ([Id], [username], [username2], [username3], [CreatedBy]) VALUES (1, N'kblau', N'mblau', N'dblau', N'acreatedby') 
INSERT [dbo].[Product] ([Id], [username], [username2], [username3], [CreatedBy]) VALUES (2, N'ausername', N'ausername2', N'ausername3', N'createdby2') 

EDMXここで次に

を作成している、あなたのクラスとコントローラ:

public interface IQuery<T> 
{ 
    IQueryable<Product> Data { get; } 
} 

public class Query : IQuery<Product> 
{ 
    public IQueryable<Product> Cache { get; set; } 

    public IQueryable<Product> Data 
    { 
     get 
     { 
      if (Cache == null) 
      { 
       //using (EFDataSource entity = new EFDataSource()) 
       //{ 
        //entity.Database.Log = x => Debug.WriteLine(x); 
        var result = new EFDataSource().Products; 
        var sql = result.ToString(); 
        Cache = result; 
        return result; 
       //} 
      } 
      else 
      { 
       return Cache; 
      } 
     } 
    } 
} 

public class FilterByCreatedBy : IQuery<Product> 
{ 
    private readonly string createdBy; 
    private readonly IQuery<Product> query; 

    public FilterByCreatedBy(IQuery<Product> query, string createdBy) 
    { 
     this.createdBy = createdBy; 
     this.query = query; 
    } 

    public IQueryable<Product> Data 
    { 
     get { return query.Data.Where(s => s.CreatedBy == createdBy); } 
    } 
} 

public class FilterBySomething : IQuery<Product> 
{ 
    private readonly string username; 
    private readonly IQuery<Product> query; 

    public FilterBySomething(IQuery<Product> query, string username) 
    { 
     this.username = username; 
     this.query = query; 
    } 

    public IQueryable<Product> Data 
    { 
     get { return query.Data.Where(s => s.username == username); } 
    } 
} 

public class HomeController : Controller 
{ 
    public ActionResult Index42() 
    { 
     // Sends to database- I will prove that these do go the db, with entity f logging 
     var query1 = new Query();         // NOT Sends to database 

     var query2 = new FilterByCreatedBy(query1, "acreatedby"); // NOT Sends to database 

     var q = query2.Data.ToList();        //added this to show getting information *Sends to database 

     FilterBySomething query3; 
     if (true) 
     { 
      query3 = new FilterBySomething(query2, "kblau"); // NOT Sends to database 
      var ap = query3.Data.ToList();      //added this to show getting information NOT Sends to database      
     } 

     return View(); 
    } 
+0

最終的にはdbcontextを必ず処分してください – kblau

関連する問題