实体框架查询装饰器立即发送查询

时间:2017-04-05 12:55:59

标签: entity-framework linq entity-framework-6

我有一个数据库上下文来获取我的数据源。

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)

这会奏效。关键是将db调用的结果存储在变量中。你可以调用这个变量&#39; Cache&#39;或者你喜欢的任何东西。

数据库:

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