2011-03-01 151 views
0

我有一個包含代理,客戶端,事務和表單的EDMX。代理的客戶有交易和交易的形式。來自SQL的LINQ-to-Entities查詢

我想要使用投影一次性獲取代理的所有實體,以便將其放入分層結構樹視圖中。樹視圖僅需在所選年份顯示事務和表單。

我在SQL查詢將是這個樣子:

SELECT c.*, t.*, f.* FROM Client c 
INNER JOIN Client_Bucket_Client cbc on cbc.Client_GUID = c.Client_GUID 
INNER JOIN Agent_Client_Bucket acb on acb.Client_Bucket_GUID = cbc.Client_Bucket_GUID 
LEFT OUTER JOIN [Transaction] t on t.Client_GUID = c.Client_GUID 
LEFT OUTER JOIN [Form] f on f.Transaction_GUID = t.Transaction_GUID 
WHERE f.Year = 2011 AND t.Year = 2011 AND acb.Agent_GUID = 'A29B6E94-3F1B-E011-B68A-001F290A2D4A' 
ORDER BY c.Last_Change_Date desc, c.File_Under 

現在我的LINQ看起來是這樣的:

var clients = from client in ObjectContext.Clients 
        join cbc in ObjectContext.Client_Bucket_Client on client.Client_GUID equals cbc.Client_GUID 
        join acb in ObjectContext.Agent_Client_Bucket on cbc.Client_Bucket_GUID equals acb.Client_Bucket_GUID 
        where acb.Agent_GUID == agentGuid 
        orderby client.Last_Change_Date descending, client.File_Under 
        select client; 

    var clientInfos = 
     from c in clients 
     select new 
     { 
      Client = c, 
      TransactionInfos = ObjectContext.Transactions 
       .Where(t => t.Client_GUID == c.Client_GUID && t.Year == year) 
       .Select(t => new 
       { 
        Transaction = t, 
        ToAttach = ObjectContext.Forms.Where(f => f.Transaction_GUID == t.Transaction_GUID && f.Year == year) 
       }) 
     }; 

    // Looping over this query will hit the database *once* 
    foreach (var info in clientInfos) 
    { 
     foreach (var transactionInfo in info.TransactionInfos) 
     { 
      transactionInfo.Transaction.Forms.Attach(transactionInfo.ToAttach); 
     } 

     var tt = info.TransactionInfos.ToList(); //.Select(t => t.Transaction); 

     var trans = tt.Select(t => t.Transaction); 

     info.Client.Transactions.Attach(trans); 
    } 

    // Return a queryable object; constructing a new query from this will hit the database one more time 
    return clients; 

但我得到一個錯誤:

負載查詢'GetTopLevelData'操作失敗。執行命令定義時發生錯誤。詳情請參閱內部例外。內部異常消息:超時已過期。操作完成之前超時的時間或服務器沒有響應。

這裏是堆棧跟蹤:

在在System.Data.Objects.Internal.ObjectQueryExecutionPlan.Execute [TResultType] System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand,的CommandBehavior行爲)(ObjectContext的上下文,ObjectParameterCollection parameterValues)at System.Data.Objects.ObjectQuery 1.GetResults(Nullable 1 forMergeOption at System.Data.Objects.ObjectQuery validationErrors,Int32 & totalCount)at System.ServiceModel.DomainServices.Hosting.QueryProcessor.Process [TEntity](DomainService domainService,DomainOperationEntry,queryOperation,Object []參數,ServiceQuery服務equery的,IEnumerable的1& validationErrors, Int32& totalCount) at System.ServiceModel.DomainServices.Hosting.QueryOperationBehavior 1.QueryOperationInvoker.InvokeCore(對象實例,對象[]輸入,對象[] &輸出)

我發現這個錯誤只發生在某些數據。似乎有些東西是空的somehwere ??

回答

0

如果你想在SQL中實現JOIN爲什麼你不在LINQ中使用JOIN

http://msdn.microsoft.com/en-us/library/bb534675.aspx

這是你會如何加入客戶的交易:

var clientTransactions = clients 
     .Join(ObjectContext.Transactions, c => c.Client_GUID, t => t.Client_GUID, 
        (c,t) => new {Client = c, Transaction = t}); 

很難預測哪些SQL查詢產生的LINQ所以我寧願用這個語法JOIN。

P.S .:你正在超時 - 這絕對取決於數據,尤其是數據量。嘗試分析你的LINQ發送給SQL服務器的查詢。

+0

感謝您的回覆,您的建議幫助我更好地理解了LINQ,但是如果您查看我發佈的SQL查詢,我需要返回客戶端,客戶端的所有事務以及所有的表單交易。我無法將兩個連接嵌套在一起。任何額外的幫助將不勝感激。 – Ruggeri 2011-03-02 16:11:08

0

我用下面的代碼解決了我的問題。我對Linq-to-Entities很陌生我不確定這是否是最好的或首選的方式,但它對我有用。

public IQueryable<Client> GetTopLevelData(Guid agentGuid, int year) 
{ 
    var clients = from client in ObjectContext.Clients 
        join cbc in ObjectContext.Client_Bucket_Client on client.Client_GUID equals cbc.Client_GUID 
        join acb in ObjectContext.Agent_Client_Bucket on cbc.Client_Bucket_GUID equals acb.Client_Bucket_GUID 
        where acb.Agent_GUID == agentGuid 
        orderby client.Last_Change_Date descending, client.File_Under 
        select client; 

    var clientTransactions = clients 
       .Join(ObjectContext.Transactions, c => c.Client_GUID, t => t.Client_GUID, 
          (c, t) => new { Transaction = t }); 

    var clientForms = clientTransactions 
       .Join(ObjectContext.Forms, t => t.Transaction.Transaction_GUID, f => f.Transaction_GUID, 
          (t, f) => new { Form = f }); 

    foreach (var client in clients) 
    { 
     var clientTrans = from trans in clientTransactions where trans.Transaction.Client_GUID == client.Client_GUID && trans.Transaction.Year == year select trans; 
     foreach (var trans in clientTrans) 
     { 
      client.Transactions.Attach(trans.Transaction); 

      var transForms = from forms in clientForms where forms.Form.Transaction_GUID == trans.Transaction.Transaction_GUID && forms.Form.Year == year select forms; 
      foreach (var form in transForms) 
      { 
       trans.Transaction.Forms.Attach(form.Form);                
      } 
     } 
    } 

    return clients; 
} 

我研究如何嵌套在LINQ的加入,但無法得到任何工作,所以在這裏我拉子事務和形式的記錄,然後加載預計客戶提供結果物件。我不再獲取超時或(Nerlable1 forMergeOption)錯誤。

感謝大家的幫助!