2011-06-14 79 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