LINQ множественное левое внешнее объединение с предложением "или" - PullRequest
1 голос
/ 15 июня 2011

Так что, в основном, я пытаюсь передать этот запрос в 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 }?Это кажется слишком странным, чтобы быть реальным.

Ответы [ 2 ]

1 голос
/ 15 июня 2011
(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 голосов
/ 15 июня 2011

Я думаю, что предложение ApplicationId на самом деле не похоже на его часть JOIN - то есть на самом деле оно не является частью отношения внешнего ключа - вместо этого это на самом деле просто нормальное условие WHERE.

Так что я бырекомендуем переместить ApplicationId в WHERE как в 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...