我有一个代理,客户,交易和表格的EDMX。代理商拥有具有交易和交易的客户有表格。
我想使用投影来立即获取代理的所有实体以放入层次结构树视图。树视图只需按所选年份显示交易和表格。
我在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.Object所述的System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand,CommandBehavior behavior),System.Data.Objects.Internal.ObjectQueryExecutionPlan.Execute [TResultType](ObjectContext context,ObjectParameterCollection parameterValues) System.Data.Objects.ObjectQuery 1.GetResults(Nullable
1&amp; 1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() at RealForms.Web.Data.RealFormsService.GetTopLevelData(Guid agentGuid, Int32 year) in C:\Users\Bryan\Documents\Visual Studio 2010\Projects\RealForms\RealForms.Web.Data\RealFormsService.cs:line 590 at GetTopLevelData(DomainService , Object[] ) at System.ServiceModel.DomainServices.Server.ReflectionDomainServiceDescriptionProvider.ReflectionDomainOperationEntry.Invoke(DomainService domainService, Object[] parameters) at System.ServiceModel.DomainServices.Server.DomainOperationEntry.Invoke(DomainService domainService, Object[] parameters, Int32& totalCount) at System.ServiceModel.DomainServices.Server.DomainService.Query(QueryDescription queryDescription, IEnumerable
1 forMergeOption validationErrors,Int32&amp; totalCount)在System.ServiceModel.DomainServices.Hosting.QueryProcessor.Process [TEntity](DomainService domainService,DomainOperationEntry queryOperation,Object []参数,ServiceQuery serviceQuery,IEnumerable 1& validationErrors, Int32& totalCount) at System.ServiceModel.DomainServices.Hosting.QueryOperationBehavior
1.QueryOperationInvoker.InvokeCore(Object instance,Object []输入,对象[]和输出)
我发现此错误仅发生在某些数据上。似乎有些东西是无效的吗?
答案 0 :(得分: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服务器的查询。
答案 1 :(得分: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中嵌套连接但是无法获得任何工作,所以在这里我拉出子事务并形成记录,然后用结果加载投影的客户端对象。我不再获得超时或(Nullable1 forMergeOption)错误。
感谢大家的帮助!