我需要在ORMLite Sql Server中执行此SQL :(如果我在参数中传递0,那么我将删除过滤器,如SQL中所示:
declare @departmentId int = 0;
declare @projectTaskStatusId int = 0;
select * from ProjectTask t
join Project p on p.ProjectId = t.ProjectId
where
(p.DepartmentId = @departmentId or @departmentId = 0) and
(t.ProjectTaskStatusId = @projectTaskStatusId or @projectTaskStatusId = 0)
我在下面创建了这个代码,但它无法正常工作,在ORMLite SQL Server中执行此操作的最佳方法是什么?
dbCon.LoadSelectAsync(x =>(x.Project.DepartmentId == departmentId || departmentId == 0)&& (x.ProjectTaskStatusId == projectTaskStatusId || projectTaskStatusId == 0));
我可以使用下面的代码使其工作(但这是使用Lambda而不是直接在OrmLite:
var tasks = await dbCon.LoadSelectAsync<ProjectTask>(x => x);
return tasks.Where(x => (departmentId == 0 || x.Project.DepartmentId.Equals(departmentId)) && (projectTaskStatusId == 0 || x.ProjectTaskStatusId.Equals(projectTaskStatusId)));
在你们的帮助下,我可以在下面做解决方案,但是,我认为这是昂贵的,因为我不能仅使用SelectReync的LoadReferences,然后我必须做一个foreach手动加载每个引用:
var query = dbCon.From<ProjectTask>()
.Join<ProjectTask, Project>((pt, p) => pt.ProjectId == p.Id)
.Where<Project>(p => p.DepartmentId == departmentId || departmentId == 0)
.And<ProjectTask>(pt => pt.ProjectTaskStatusId == projectTaskStatusId || projectTaskStatusId == 0);
var tasks = await dbCon.SelectAsync(query);
// Load the references
foreach (var item in tasks)
{
if (item.ProjectId > 0)
item.Project = await dbCon.SingleByIdAsync<Project>(item.ProjectId);
if (item.AssignedToId > 0)
item.AssignedTo = await dbCon.SingleByIdAsync<Employee>(item.AssignedToId);
if (item.RequestedById > 0)
item.RequestedBy = await dbCon.SingleByIdAsync<Employee>(item.RequestedById);
if (item.ProjectTaskStatusId > 0)
item.ProjectTaskStatus = await dbCon.SingleByIdAsync<ProjectTaskStatus>(item.ProjectTaskStatusId);
}
return tasks;
答案 0 :(得分:1)
我现在没有代码在我面前,所以我可能会对语法有所了解,但我认为以下代码将转换为等效查询。
var query = db.From<ProjectTask>()
.Join<ProjectTask, Project>((pt, p) => pt.ProjectId == p.ProjectId)
.Where<Project>(p => p.DepartmentId == departmentId || departmentId == 0)
.And<ProjectTask>(pt => pt.ProjectTaskStatusId == statusId || statusId == 0);
var tasks = await dbCon.SelectAsync<ProjectTask>(query);
免责声明:这是针对Servicestack.OrmLite版本4.0+及其新的漂亮的SqlExpression类。
更新
好的,我知道你现在要做的是什么
是的,在这样的for循环中加载引用不是非常有效的解决方案。我不确定为什么LoadSelect
方法不起作用(如果你有一个很好的复制测试,你可能想报告这个可能的错误),但可能有一个解决方法。
如果你深入研究OrmLite源代码并检查它实际上做了什么,你可以看到在LoadSelect
的封面下实际完成的是查询首先运行然后OrmLite迭代模型定义并发出表格的查询
SELECT columns FROM table WHERE id IN (originalquery)
每个参考文献。然后它获取该查询的结果并将结果连接到引用。因此,当使用LoadSelect
时,OrmLite实际上会在这里发出几个查询,尽管每个引用将是1个查询,而不是每个对象每个引用1个查询,这要好得多。
您可以手动执行此策略。虽然这会有点麻烦......我现在没有给你任何代码,因为我现在没有在我面前有VS的电脑,而且这有点先进,所以我不喜欢我想我能猜到这一点。
但是,你真的需要所有这些参考吗?我现在只是在猜测,但这看起来像是你要一次加载的大量数据。你真的需要所有这些参考和专栏吗?或者你只需要几个?如果您只需要其中的几个,那么您可能希望将连接添加到自定义模型中,而只使用您实际需要的列。这将是性能最高的选项,因为您可以在一个查询中执行此操作,并且只传输您实际需要的数据而不是所有内容。但我不知道你是如何使用这些数据的,所以这可能不是一个好的选择。 :)
但如上所述,您可能在LoadSelect
中发现了一个错误!我强烈建议你将它添加到问题跟踪器,看看他们是否会修复它 - 根据我的经验,ServiceStack在响应和修复错误方面非常快。特别是如果你给它们一个可重复的单元测试(你很可能很容易从你的代码中提取)。