我有一些业务逻辑,api和一个使用数据库来存储数据的作业管理器都使用它。简化如下:。
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();
}
}
在功能上这有效,但存在问题。
如果我尝试使用db处理器中的dbcontext获取数据,则mysql服务器收到的结果查询是:
SELECT
`Extent1`.`RequestID`,
`Extent1`.`RequestType`,
`Extent1`.`StatusId`
FROM `Requests` AS `Extent1`
WHERE (0 = `Extent1`.`StatusId`)
(注意WHERE子句)
在上面的BusinessLogic类中运行相同的代码时,生成的查询为:
SELECT
`Extent1`.`RequestID`,
`Extent1`.`RequestType`,
`Extent1`.`StatusId`
FROM `Requests` AS `Extent1`
缺少Where子句,这意味着正在检索整个表,然后将where子句应用于内存中的数据
无论如何设计公共类,以便在使用dbset调用它时将where子句发送到db?
编辑:要明确,IQueryable不是一个选项,因为List不会继承它,这是api处理器使用的。但是,在api处理器中使用List不是强制性的
谢谢!
答案 0 :(得分:0)
尝试使用
IQuerable<Request> Requests
而不是
IEnumerable<Request> Requests
更新: 您可以使用存储库模式。我使用this模式,它非常轻巧且可扩展。
答案 1 :(得分:0)
您可以使用IQuerable<Request>
代替IEnumerable<Request>
。
但是,为了维护BusinessLogic
,单独的IQuerable<Request>
课程并不常见。
那些需要数据的人可以直接拨打_db.Requests
。
var result = _db.Requests
.Where(r => r.StatusId == Constants.STATUS_NOT_PROCESSED_ID)
.ToList()
或者,您可以创建一个类似this的存储库层来保留所有逻辑。
如果您不同意上述方法,可以使用 Specification pattern 。