2011-06-14 40 views
1

所以基本上,我尝试在LINQ中传输此查询。使用“或”子句的LINQ多个左外连接

DECLARE @p1 UniqueIdentifier SET @p1 = 'AC1D85C1-28F1-46A3-9C6A-3B7446609A2A' 
DECLARE @p2 UniqueIdentifier SET @p2 = NEWID() 
SELECT 
    [MTD].[Description], 
    [MTD].[MessageTypeID], 
    ISNULL([AMT].[ApplicationMessageTypeID], NEWID()), 
    ISNULL([AMT].[EventForwardingRuleID], '1001') 
FROM [dbo].[MessageType] as [MT] 
INNER JOIN [dbo].[MessageTypeDescription] AS [MTD] 
     ON [MT].[MessageTypeID] = [MTD].[MessageTypeID] 
LEFT OUTER JOIN [dbo].[ApplicationMessageType] AS [AMT] 
     ON [AMT].[MessageTypeID] = [MT].[MessageTypeID] 
     AND ([AMT].[ApplicationID] = @p1 OR [AMT].[ApplicationID] IS NULL) 
WHERE [MTD].[Culture] = 'fr' 

我知道大部分的查询看起来应该像这样的事情:

(from mt in db.MessageTypes 
join mtd in db.MessageTypeDescriptions 
    on mt.MessageTypeID equals mtd.MessageTypeID 
join amt in db.ApplicationMessageTypes 
    on new { mt.MessageTypeID, (applicationId || null) } equals new { amt.MessageTypeID, amt.ApplicationID } 
    into appMessageTypes 
from amt in appMessageTypes.DefaultIfEmpty() 
where mtd.Culture == culture 
select new ApplicationEditEventTypeModel 
{ 
    ApplicationMessageTypeID = amt.ApplicationMessageTypeID == null ? Guid.NewGuid() : amt.ApplicationMessageTypeID, 
    Description = mtd.Description, 
    MessageTypeID = mtd.MessageTypeID, 
    EventForwardingRuleID = amt.EventForwardingRuleID == null ? 0 : amt.EventForwardingRuleID 
}); 

在这里,我真的不知道该部分是“ApplicationMessageTypes”的一部分。对于多个左连接查询,我会使用new {} equals new {}构造,但在这种情况下,我有2个子句([AMT].[ApplicationID] = @p1 OR [AMT].[ApplicationID] IS NULL)

我应该使用类似new { mt.MessageTypeID, new { applicationId ,null }} equals new { amt.MessageTypeID, amt.ApplicationID }的东西吗?这似乎太奇怪,不真实。

回答

1
(from mt in db.MessageTypes 
join mtd in db.MessageTypeDescriptions 
    on mt.MessageTypeID equals mtd.MessageTypeID 
from amt in db.ApplicationMessageTypes 
    .Where(a => a.MessageTypeID == mt.MessageTypeID && 
      (a.ApplicationID == applicationId || !a.ApplicationID.HasValue)).DefaultIfEmpty() 
where mtd.Culture == culture 
select new ApplicationEditEventTypeModel 
{ 
    ApplicationMessageTypeID = amt.ApplicationMessageTypeID ?? Guid.NewGuid(), 
    Description = mtd.Description, 
    MessageTypeID = mtd.MessageTypeID, 
    EventForwardingRuleID = amt.EventForwardingRuleID ?? 0 
}); 
+0

正是我在找的东西!谢谢! – Erick 2011-06-15 12:56:35

0

我认为ApplicationId子句看起来并不像它的JOIN部分 - 即它不是外键关系的一部分 - 相反它实际上只是一个正常的WHERE条件。

所以我建议你移动的applicationID出其中两个SQL和LINQ的

DECLARE @p1 UniqueIdentifier SET @p1 = 'AC1D85C1-28F1-46A3-9C6A-3B7446609A2A' 
DECLARE @p2 UniqueIdentifier SET @p2 = NEWID() 
SELECT 
    [MTD].[Description], 
    [MTD].[MessageTypeID], 
    ISNULL([AMT].[ApplicationMessageTypeID], NEWID()), 
    ISNULL([AMT].[EventForwardingRuleID], '1001') 
FROM [dbo].[MessageType] as [MT] 
INNER JOIN [dbo].[MessageTypeDescription] AS [MTD] 
     ON [MT].[MessageTypeID] = [MTD].[MessageTypeID] 
LEFT OUTER JOIN [dbo].[ApplicationMessageType] AS [AMT] 
     ON [AMT].[MessageTypeID] = [MT].[MessageTypeID] 
WHERE [MTD].[Culture] = 'fr' 
     AND (AMT IS NULL OR ([AMT].[ApplicationID] = @p1 OR [AMT].[ApplicationID] IS NULL)) 

(from mt in db.MessageTypes 
join mtd in db.MessageTypeDescriptions 
     on mt.MessageTypeID equals mtd.MessageTypeID 
join amt in db.ApplicationMessageTypes 
     on new mt.MessageTypeID equals amt.MessageTypeID 
    into appMessageTypes 
from amt in appMessageTypes.DefaultIfEmpty() 
where mtd.Culture == culture 
     && amt==null || (amt.ApplicationID == null || amt.ApplicationID == applicationId) 
select new ApplicationEditEventTypeModel 
{ 
ApplicationMessageTypeID = amt.ApplicationMessageTypeID == null ? Guid.NewGuid() : amt.ApplicationMessageTypeID, 
Description = mtd.Description, 
MessageTypeID = mtd.MessageTypeID, 
EventForwardingRuleID = amt.EventForwardingRuleID == null ? 0 : amt.EventForwardingRuleID 
}); 

你也许还使用了嵌套查询(或视图)如果您想要使ApplicationId子句更接近原始ApplicationMessageType表

+0

这并不坏实际上是我第一次尝试解决这个问题。不幸的是它需要在“加入”条款中。 – Erick 2011-06-15 12:57:26