2017-06-16 33 views
4

有這個查詢我得到一個InvalidOperationException:「單個聚合應用到的集合必須是空的或只包含一個項目」。如何解決「單個聚合應用於的集合必須爲空或者只包含一個項目」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(); 

我希望當我做連接,以獲得只有具有特定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生成了第一個列表,然後我用另一個規範生成了另一個列表。稍後我會對任務做一個簡單的查詢。

// 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(); 

我只是希望,這將工作,無論客戶的數據庫結構,雙排引用或使... :)

+0

你很高興展示你的完整調用堆棧,但是如果你沒有給出你的代碼片段的過程的名稱,它沒有多大用處。 processException中的異常,而不是ProcessAnalyzeAndExecQuery中的異常。你確定你的代碼片段來自processException嗎? –

+0

上面的代碼位於ChangeStatusToPickedToShipToStageOrStaged()方法中。 –

+0

不知道它是否有幫助,但你可以嘗試聲明'var first = new XPQuery (session,true)'和'var second = new XPQuery (session,true)' ,然後在你的查詢中使用它們,例如'(從第一次加入ols到第二個''。 –

回答

1

在查詢中選擇部分實例化一個持久性對象,這意味着每一個元素在結果序列中是唯一的(一個持久對象不能被加載到同一個Session中兩次)。這就是爲什麼查詢被轉換爲單個聚合函數的原因。錯誤的原因是Join表達式中的innerKey和outerKey的匹配可能會產生從外部序列中選擇的項目的重複條目。

如果在您的方案中不需要重複,那麼您需要修復數據庫中的數據或重寫查詢以將其考慮在內。例如,你可以使用「加入到」操作員組重複記錄:

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語句,以便查詢並不需要實例持久對象。如果以上都不適用,請直接聯繫DevExpress Support Service。你的問題對於XPO來說太具體了,所以你可能會在那裏獲得合格的答案。

+0

好吧,我已經嘗試了所有3個建議。他們沒有那麼多幫助我,但至少他們指導我採取另一種方法。我會用當前的解決方案更新我的問題... 順便說一句:在第一個建議tg.Key是未知的(我還沒有用'進'關鍵字在LINQ) –

相關問題