执行此查询后,我得到了一个InvalidOperationException:“应用单个聚合的集合必须为空或恰好包含一项”。
List<int> olsesUsedForTaskCompletion = new List<int>();
olsesUsedForTaskCompletion.AddRange(task.OrderLineSpecifications_QtysCompleted.Select(ols => ols.Key).ToList());
var allRelatedTasks = (from t in new XPQuery<Core.Model.Task.Task>(session, true)
join ols in new XPQuery<OrderLineSpecification>(session, true)
on t.PickSpecification equals ols.PickSpecification
where t.PickSpecification == task.PickSpecification
&& t.Status != TaskStatuses.Cancelled
&& olsesUsedForTaskCompletion.Contains(ols.Oid)
select t).ToList();我希望当我做join时,只得到具有特定Id的OLS。我做错了什么?
这是堆栈跟踪:
at DevExpress.Xpo.Helpers.InTransactionLoader.ProcessException(Exception ex)
at DevExpress.Xpo.Helpers.InTransactionLoader.ProcessAnalyzeAndExecQuery()
at DevExpress.Xpo.Helpers.InTransactionLoader.Process()
at DevExpress.Xpo.Helpers.InTransactionLoader.GetObjects(ObjectsQuery[] queries)
at DevExpress.Xpo.Helpers.InTransactionLoader.GetObjects(Session session, ObjectsQuery[] queries)
at DevExpress.Xpo.Session.<>c__DisplayClass16.<GetObjectsInTransaction>b__14()
at DevExpress.Xpo.Logger.LogManager.Log[T](String category, LogHandler`1 handler, MessageHandler`1 createMessageHandler)
at DevExpress.Xpo.Session.GetObjectsInTransaction(XPClassInfo classInfo, CriteriaOperator condition, SortingCollection sorting, Int32 skipSelectedRecords, Int32 topSelectedRecords, Boolean selectDeleted)
at DevExpress.Xpo.XPQueryBase.SessionGetObjects(XPClassInfo classInfo, CriteriaOperator condition, SortingCollection sorting, Int32 skipSelectedRecords, Int32 topSelectedRecords, Boolean selectDeleted)
at DevExpress.Xpo.XPQueryBase.GetObjects()
at DevExpress.Xpo.XPQueryBase.Enumerate(Type type)
at DevExpress.Xpo.XPQuery`1.GetEnumerator()
at DevExpress.Xpo.XPQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Davanti.WMS.Services.Implementation.Outbound.OrderLineSpecificationStatusService.ChangeStatusToPickedToShipToStageOrStaged(Session session, IList`1 tasks, IList`1 olsWithoutTasks) in c:\Corax\DAV_WMS\DEV\SRC\APP\WMS\Davanti.WMS.Services.Implementation\Outbound\OrderLineSpecificationStatusService.cs:line 471更新:在经历了一些挣扎之后,这里是我所做的:-用了另一种方法。我不知道您是否能理解它的业务逻辑,但我首先用OLS生成了一个列表,然后用它生成了另一个带有pick规范的列表。稍后,我对任务执行一个简单的查询。
// compose list of olses for which status will be updated
List<OrderLineSpecification> olSpecs = (from ols in new XPQuery<OrderLineSpecification>(session, true)
where ols.Status != OrderLineSpecificationStatus.Cancelled
//...
&& ols.PickSpecification == task.PickSpecification
&& (olsesUsedForTaskCompletion.Count == 0
|| (olsesUsedForTaskCompletion.Contains(ols.Oid) && ols.QtyOrdered == ols.QtyPicked))
select ols).ToList();
var pickSpecificationKeys = (from ols in olSpecs select ols.PickSpecification.Oid).Distinct().ToList();
var allRelatedTasks = (from t in new XPQuery<Core.Model.Task.Task>(session, true)
where pickSpecificationKeys.Contains(t.PickSpecification.Oid)
&& t.Status != TaskStatuses.Cancelled
select t).ToList();我只希望这能行得通,不管客户端的数据库结构、双重引用还是其他的……:)
发布于 2017-06-19 23:31:43
查询中的Select部分实例化一个持久对象,这意味着结果序列中的每个元素都是唯一的(一个持久对象不能两次加载到同一个会话中)。这就是为什么查询被转换为单个聚合函数的原因。错误的原因是,连接表达式中的innerKey和outerKey的匹配可能会产生从外部序列中选择的重复条目。3.
如果您的场景中不需要重复项,则需要修复数据库中的数据或重写查询以考虑到这一点。例如,您可以使用"join into“操作符对重复的记录进行分组:
from t in new XPQuery<Core.Model.Task.Task>(session, true)
join ols in new XPQuery<OrderLineSpecification>(session, true)
on t.PickSpecification equals ols.PickSpecification
into tg
where tg.key == task.PickSpecification
&& tg.Any(gi.Status != TaskStatuses.Cancelled && olsesUsedForTaskCompletion.Contains(ols.Oid))
select t在某些情况下,替换查询中的序列也可能有助于避免错误,但在结果序列中会有重复的对象引用:
from ols in new XPQuery<OrderLineSpecification>(session, true)
join t in new XPQuery<Core.Model.Task.Task>(session, true)
on ols.PickSpecification equals t.PickSpecification
where ols.PickSpecification == task.PickSpecification
&& t.Status != TaskStatuses.Cancelled
&& olsesUsedForTaskCompletion.Contains(ols.Oid)
select t如果您对结果序列中的重复记录没有意见,我建议您只需向Select语句添加一个投影,这样查询就不需要实例化持久对象。
from t in new XPQuery<Core.Model.Task.Task>(session, true)
join ols in new XPQuery<OrderLineSpecification>(session, true)
on t.PickSpecification equals ols.PickSpecification
where t.PickSpecification == task.PickSpecification
&& t.Status != TaskStatuses.Cancelled
&& olsesUsedForTaskCompletion.Contains(ols.Oid)
select new { SomeProperty = t.SomeProperty, AnotherProperty = t.AnotherProperty }PS:如果以上方法都不适用于您的特定情况,请直接联系DevExpress Support Service。您的问题对于XPO来说太具体了,所以您很可能会在那里获得合格的答案。
https://stackoverflow.com/questions/44582031
复制相似问题