2017-04-05 39 views
0

我有一個數據庫上下文來獲取我的數據源。實體框架查詢裝飾器立即發送查詢

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); } 
    } 
} 

但是所有這些步驟都會向數據庫發送查詢。但我只想發送一個查詢。

+0

什麼是你的過濾方法中的代碼? –

+0

我更新了帖子 – barteloma

+0

聽起來像調試器的經驗問題。如果你不執行它(評估,在一些調試器窗口中擴展enumerable),那麼'IQueryable '不會被髮送到數據庫。 –

回答

0

這將工作。關鍵是將db調用的結果存儲在一個變量中。你可以調用這個變量'Cache'或任何你喜歡的東西。

數據庫:

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