LINQ的2个级别的连接

时间:2012-07-10 15:17:11

标签: c# linq entity-framework .net-4.0

我需要将3个对象链接在一起

父级:TblClients
这将有多个TblBusinessLeads类型的子项,两者之间的关键是ClientID
类型Lead将有多个类型为TblFeeBreakouts的子项,两者之间的关键是LeadID

我已经编写了以下LINQ来获取数据包,但它没有回来(内存异常)

from t0 in TblClients
join t1 in TblBusinessLeads on t0.ClientID equals t1.ClientID into t1_join
from t1 in t1_join.DefaultIfEmpty()
join t3 in TblFeeBreakouts on t1.LeadID equals t3.LeadID into t3_join
from t3 in t3_join.DefaultIfEmpty()
orderby
t0.ClientID,
t1.LeadID
select new {
            client_data = t0,
            business_lead_data = t1_join,
            fee_breakout_data = t3_join
}

我不确定你甚至可以做到这一点,但这个想法似乎很常见。任何帮助将不胜感激。谢谢

修改
哇很多评论。这是我的答案 我试图在LinqPad中运行查询,这就是内存不足的地方 如果我查看生成的SQL,它会给我

SELECT [t0].[ClientID], [t0].[ClientName], [t0].[ClientDesc], [t0].[EditedBy], [t0].[EditedDate], [t0].[CreatedBy], [t0].[CreatedDate], [t3].[LeadID], [t3].[InitiativeName], [t3].[Description], [t3].[NewBusNeeds], [t3].[CreativeNeeds], [t3].[IdeationNeeds], [t3].[Comments], [t3].[LossReasons], [t3].[OriginDate], [t3].[DateReceivedAssignment], [t3].[DueDate], [t3].[TimelineNotes], [t3].[PendingCode], [t3].[EstStartDate], [t3].[EstEndDate], [t3].[ExeStartDate], [t3].[ExeEndDate], [t3].[Probable80Total], [t3].[Possible50Total], [t3].[Emerging25Total], [t3].[NoBudget0Total], [t3].[TotalBudget], [t3].[FinancialNotes], [t3].[DollarsRecordFor], [t3].[BizDevContactUserID], [t3].[BizDevContact2UserID], [t3].[SVPContactUserID], [t3].[ClientMgmtContactUserID], [t3].[CMAdditionalContactUserID], [t3].[AdditionalContactUserID], [t3].[CreatorUserID], [t3].[OfficeID], [t3].[ClientID] AS [ClientID2], [t3].[LeadTypeID], [t3].[ActionNeeded], [t3].[ActionDate], [t3].[NewBusDeliveryDate], [t3].[NewBusDesc], [t3].[CreativeDeliveryDate], [t3].[CreativeDesc], [t3].[IdeationDeliveryDate], [t3].[IdeationDesc], [t3].[AltMediaDeliveryDate], [t3].[AltMediaDesc], [t3].[MobileOpsDeliveryDate], [t3].[MobileOpsDesc], [t3].[EventsDeliveryDate], [t3].[EventsDesc], [t3].[Routing], [t3].[RoutingDate], [t3].[Deleted], [t3].[LeadSourceID], [t3].[NatureofLeadID], [t3].[NatureofLeadNotes], [t3].[EditedBy] AS [EditedBy2], [t3].[EditedDate] AS [EditedDate2], [t3].[CreatedBy] AS [CreatedBy2], [t3].[CreatedDate] AS [CreatedDate2], [t3].[ClientContactName], [t3].[ClientContactTitle], [t3].[ReportingYear], (
SELECT COUNT(*)
FROM [tblBusinessLead] AS [t4]
WHERE [t0].[ClientID] = [t4].[ClientID]
) AS [value], [t1].[LeadID] AS [LeadID2]
 FROM [tblClient] AS [t0]
 LEFT OUTER JOIN [tblBusinessLead] AS [t1] ON [t0].[ClientID] = [t1].[ClientID]
LEFT OUTER JOIN [tblFeeBreakout] AS [t2] ON [t1].[LeadID] = [t2].[LeadID]
 LEFT OUTER JOIN [tblBusinessLead] AS [t3] ON [t0].[ClientID] = [t3].[ClientID]
 ORDER BY [t0].[ClientID], [t1].[LeadID], [t2].[LeadID], [t2].[FeeTypeID], [t3].    [LeadID]

这会返回120万行

模型中没有映射,因为DB没有关系(它们是推断的,没有外键或类似的东西)

我使用t1_join和t3_join的原因是因为如果我使用t1或t3,我得到单个实体,而不是对象的IEnumerable,因此我无法循环它。

如果您有更多问题,请询问。

2 个答案:

答案 0 :(得分:0)

首先,客户可能会使用120万行?没有真正好的用例,所以你的第一步应该是弄清楚如何适当地过滤你的结果。

其次,我相信您的查询返回OutOfMemoryException的原因是因为LinQPad正在执行ToList()或类似的操作,以便我可以在底部窗格中显示查询结果。 ToList()将所有120万行加载到内存中。如果您在常规.Net应用中运行查询,则以下内容将返回IQueryable<>,该内容将无法加载到内存中。

var query = 
from t0 in TblClients
join t1 in TblBusinessLeads on t0.ClientID equals t1.ClientID into t1_join
from t1 in t1_join.DefaultIfEmpty()
join t3 in TblFeeBreakouts on t1.LeadID equals t3.LeadID into t3_join
from t3 in t3_join.DefaultIfEmpty()
orderby
t0.ClientID,
t1.LeadID
select new {
            client_data = t0,
            business_lead_data = t1_join,
            fee_breakout_data = t3_join
};

答案 1 :(得分:0)

如上所述,在这些表上设置asociations可能是个好主意,我做了...关联后的结果的LINQ很简单

var clientList =(来自tblClients中的一个)                               选择a).ToList();

从那里它只是访问属性。