ServiceStack ORMLite Sql 服务器 *可选过滤器
ServiceStack ORMLite Sql Server *optional filter
我需要在 ORMLite Sql 服务器中执行此操作 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 服务器中执行此操作的最佳方法是什么?
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)));
在你们的帮助下,我可以做下面的解决方案,但是,我认为它是昂贵的,因为我不能只使用 SelectAsync 的 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;
我现在手边没有代码,所以我可能对语法有点偏离,但我认为以下代码将转换为等效查询。
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)
对于每个参考文献。然后它获取该查询的结果并将结果连接到引用。因此,OrmLite 在使用 LoadSelect
时实际上会在这里发出多个查询,尽管每个引用 1 个查询而不是每个对象每个引用 1 个查询,这要好得多。
您可以手动执行此策略。虽然这会有点麻烦......我现在不会给你任何代码,因为我现在没有一台装有 VS 的电脑,而且它更高级一些,所以我不我想我能猜到这个。
但是,您真的需要所有这些参考资料吗?我现在只是在猜测,但这看起来像是您一次性加载的大量数据。您真的需要所有这些参考文献和专栏,还是只需要其中的几个?如果您真的只需要其中的几个,您可能想要连接到一个自定义模型中,而只包含您实际需要的列。这将是性能最高的选项,因为您将能够在一个查询中完成此操作,并且只传输您实际需要的数据而不是所有数据。但我不知道你是如何使用这些数据的,所以这可能不是一个好的选择。 :)
但是如前所述,您可能在 LoadSelect
中发现了错误!我强烈建议您将它添加到问题跟踪器中,看看他们是否会修复它——根据我的经验,ServiceStack 在响应和修复错误方面确实非常快。特别是如果你给他们一个可重现的单元测试(你可以很容易地从你的代码中提取它)。
我需要在 ORMLite Sql 服务器中执行此操作 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 服务器中执行此操作的最佳方法是什么?
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)));
在你们的帮助下,我可以做下面的解决方案,但是,我认为它是昂贵的,因为我不能只使用 SelectAsync 的 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;
我现在手边没有代码,所以我可能对语法有点偏离,但我认为以下代码将转换为等效查询。
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)
对于每个参考文献。然后它获取该查询的结果并将结果连接到引用。因此,OrmLite 在使用 LoadSelect
时实际上会在这里发出多个查询,尽管每个引用 1 个查询而不是每个对象每个引用 1 个查询,这要好得多。
您可以手动执行此策略。虽然这会有点麻烦......我现在不会给你任何代码,因为我现在没有一台装有 VS 的电脑,而且它更高级一些,所以我不我想我能猜到这个。
但是,您真的需要所有这些参考资料吗?我现在只是在猜测,但这看起来像是您一次性加载的大量数据。您真的需要所有这些参考文献和专栏,还是只需要其中的几个?如果您真的只需要其中的几个,您可能想要连接到一个自定义模型中,而只包含您实际需要的列。这将是性能最高的选项,因为您将能够在一个查询中完成此操作,并且只传输您实际需要的数据而不是所有数据。但我不知道你是如何使用这些数据的,所以这可能不是一个好的选择。 :)
但是如前所述,您可能在 LoadSelect
中发现了错误!我强烈建议您将它添加到问题跟踪器中,看看他们是否会修复它——根据我的经验,ServiceStack 在响应和修复错误方面确实非常快。特别是如果你给他们一个可重现的单元测试(你可以很容易地从你的代码中提取它)。