简体   繁体   English

如何设计一个通用类来接受列表和dbset

[英]How to design a common class to accept a list and dbset

I have some business logic that is used by both an api and a job manager which uses a database to store data. 我有一些由api和使用数据库存储数据的作业管理器使用的业务逻辑。 simplified like this:. 简化如下:

class BusinessLogic 
{
    public IEnumerable<Request> Requests {get;set;}

    public List<Requests> GetData()
    {
         return Requests.Where(r => r.StatusId == Constants.STATUS_NOT_PROCESSED_ID).ToList();
    }
}

class apiprocessor
{
    public void Process()
    {
        var requests = new List<Request>();

        BusinessLogic.Requests = requests;
        BusinessLogic.GetData();
    }
}

class dbprocessor
{
    private DbContext _db;

    public void Process()
    {
        //this sends the where clause to the db
        //var requests = _db.Requests.Where(r => r.StatusId == Constants.STATUS_NOT_PROCESSED_ID).ToList();

        BusinessLogic.Requests = _db.Requests;  //type DbSet<Request> Requests
        //this one doesnt
        BusinessLogic.GetData();
    }
}

functionally this works but there is a problem. 从功能上讲这可行,但是存在问题。

if i try and get the data using the dbcontext in the db processor the resulting query that the mysql server receives is: 如果我尝试使用数据库处理器中的dbcontext获取数据,则mysql服务器收到的查询结果为:

SELECT
`Extent1`.`RequestID`, 
`Extent1`.`RequestType`, 
`Extent1`.`StatusId`
FROM `Requests` AS `Extent1`
 WHERE (0 = `Extent1`.`StatusId`)

(notice the WHERE clause) (注意WHERE子句)

when the same code is run in the BusinessLogic class above, the resulting query is: 当在上面的BusinessLogic类中运行相同的代码时,结果查询为:

SELECT
`Extent1`.`RequestID`, 
`Extent1`.`RequestType`, 
`Extent1`.`StatusId`
FROM `Requests` AS `Extent1`

the Where clause is missing which means that the entire table is being retrieved and then the where clause is being applied to the data in memory 缺少Where子句,这意味着将检索整个表,然后将where子句应用于内存中的数据

is there anyway to design the common class so that when it gets called with a dbset it sends the where clause to the db? 无论如何,有没有设计公共类,以便当它被dbset调用时将where子句发送到db?

EDIT: To be clear, IQueryable is not an option because List does not inherit from it which is what the api processor uses. 编辑:要明确,IQueryable不是一个选项,因为List不会从它继承,这是api处理器使用的东西。 However, using a List in the api processor is not mandatory 但是,在api处理器中使用列表不是强制性的

Thanks! 谢谢!

Try using 尝试使用

IQuerable<Request> Requests

instead of 代替

IEnumerable<Request> Requests

Update: You can use a repository pattern. 更新:您可以使用存储库模式。 I use this pattern which is very lightweight and extendable. 我用这个模式,这是非常轻便且可扩展的。

You could use IQuerable<Request> instead of IEnumerable<Request> . 您可以使用IQuerable<Request>代替IEnumerable<Request>

However, it is not common to have a separate BusinessLogic class just to maintain IQuerable<Request> . 但是,仅具有单独的BusinessLogic类来维护IQuerable<Request>并不常见。

Those whoever needs the data could have called straight to _db.Requests . 那些需要数据的人可以直接调用_db.Requests

var result = _db.Requests
   .Where(r => r.StatusId == Constants.STATUS_NOT_PROCESSED_ID)
   .ToList()

Or, you could just create a repository layer like this to keep all logic. 或者,您可以像这样创建一个存储库层以保留所有逻辑。

If you do not like neither of above approach, you can use Specification pattern . 如果您不喜欢上述两种方法,则可以使用Specification pattern

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM