我正在尝试在NHibernate中重新创建以下查询:
SELECT DISTINCT
orderid ,
tasktype
FROM "Task"
WHERE orderid IN ( SELECT orderid
FROM "Task"
GROUP BY orderid
HAVING COUNT(orderid) > 1 )
ORDER BY orderid
在NH中,我需要一个QueryOver,它根据订单ID返回任务类型列表。基本上,我正在迭代每个任务,并且对于每次发生多次的任务(由于不同的任务类型),我需要将所有这些任务添加到返回给客户端的列表中。这是我迄今为止尝试过的NH。
var taskList = new List<Task>();
PendingTasks = session.QueryOver<Model.Task>()
.WhereRestrictionOn(c => c.OrderId).IsIn(taskList)
.SelectList
(list => list
.SelectGroup(b => b.OrderId)
.Select(b => b.TaskType)
)
.Where(Restrictions.Eq(Projections.Count<Model.Task>(x => x.OrderId), taskList.Count() > 1))
.TransformUsing((Transformers.AliasToBean<TaskType>()))
.List<TaskType>()
我刚刚开始NH,并在这里找到了一些关于分组和使用的例子。我返回到客户端的模型的属性在这里,TaskType是一个简单的枚举。
public List<TaskType> PendingTasks { get; set; }
在我看来,到目前为止,QueryOver试图返回一个IList,而不是我的目标类型的List,但是没有.ToList(),所以我不知道它会返回什么。任何与上述sql查询匹配的帮助都是有帮助的。
更新:整个方法:
private static readonly string[] TaskTypeKeys = Enum.GetNames(typeof(TaskType));
var tasksByType = new List<TaskGroup>();
Task taskObject = null;
QueryOver subQuery = QueryOver.Of<Task>()
.Select(
Projections.GroupProperty(
Projections.Property<Task>(t => t.OrderId)
)
)
.Where(Restrictions.Gt(Projections.Count<Task>(t => t.OrderId), 1));
foreach (var type in TaskTypeKeys)
{
TaskType typeEnum;
Enum.TryParse(type, out typeEnum);
var tasks = session.QueryOver<Model.Task>()
.Where(
task =>
task.TaskType == typeEnum &&
task.Completed == false &&
task.DueDate <= DateTime.Today
)
.OrderBy(t => t.DueDate).Asc
.List<Model.Task>()
.Select(t => new Task()
{
Id = t.Id,
OrderId = t.OrderId,
CustomerId = t.CustomerId,
CustomerName = t.CustomerName,
GroupName = t.GroupName,
TripDate = t.TripDate,
TaskType = TaskTypeTitles[t.TaskType.ToString()],
DueDate = t.DueDate,
Completed = t.Completed,
IsActiveTask = t.IsActiveTask,
PendingTasks = session.QueryOver<Task>(() => taskObject)
// the WHERE clause: OrderId IN (subquery)
.WithSubquery
.WhereProperty(() => taskObject.OrderId)
ERROR-------> .In(subQuery)
// the rest of your SELECT/projections and transformation
.SelectList(list => list
.SelectGroup(b => b.OrderId)
.Select(b => b.TaskType)
)
.TransformUsing((Transformers.AliasToBean<TaskType>()))
.List<TaskType>()
}
).ToList();
tasksByType.Add(new TaskGroup()
{
Title = TaskTypeTitles[type.ToString()],
Content = tasks,
RemainingCount = tasks.Count(),
OverdueCount =
tasks.Count(
task =>
task.DueDate < DateTime.Today),
});
};
return tasksByType;
方法的类型参数&#39; NHibernate.Criterion.Lambda.QueryOverSubqueryPropertyBuilderBase,Api.Task,Api.Task&gt; .In(NHibernate.Criterion.QueryOve r)&#39;无法从使用中推断出来。尝试明确指定类型参数。
答案 0 :(得分:3)
在这种情况下,子查询语法将对我们有所帮助。首先,让我们用这种方式声明内部选择:
QueryOver<Task> subQuery = QueryOver.Of<Task>()
.Select(
Projections.GroupProperty(
Projections.Property<Task>(t => t.OrderId)
)
)
.Where(Restrictions.Gt(Projections.Count<Task>(t => t.OrderId), 1))
;
这将产生:
(SELECT this_0_.OrderId as y0_
FROM [Task] this_0_
GROUP BY this_0_.OrderId
HAVING count(this_0_.OrderId) > 1)
现在我们可以将它用作外部SELECT
:
Task task = null;
var PendingTasks =
session.QueryOver<Task>(() => task)
// the WHERE clause: OrderId IN (subquery)
.WithSubquery
.WhereProperty(() => task.OrderId)
.In(subQuery)
// the rest of your SELECT/projections and transformation
.SelectList(list => list
.SelectGroup(b => b.OrderId)
.Select(b => b.TaskType)
)
.TransformUsing((Transformers.AliasToBean<TaskType>()))
.List<TaskType>()
;
这将创建其余部分,包含子查询