что не так в этом LINQ Synatx? - PullRequest
1 голос
/ 15 мая 2010

Я пытаюсь преобразовать запрос SQL в LINQ. Каким-то образом моя логика подсчета (отличная (x)), кажется, не работает правильно. Исходный SQL довольно эффективен (или я так думаю), но сгенерированный SQL даже не возвращает правильный результат.

Я пытаюсь исправить это LINQ, чтобы делать то, что делает исходный SQL, И эффективно, как делает исходный запрос. Помощь здесь будет очень цениться, так как я застрял здесь: (

SQL, который работает, и мне нужно сделать сопоставимый LINQ из:

SELECT  [t1].[PersonID] AS [personid]
FROM [dbo].[Code] AS [t0]
INNER JOIN [dbo].[phonenumbers] AS [t1] ON [t1].[PhoneCode] = [t0].[Code]
INNER JOIN [dbo].[person] ON [t1].[PersonID]= [dbo].[Person].PersonID
WHERE ([t0].[codetype] = 'phone') AND (
([t0].[CodeDescription] = 'Home') AND ([t1].[PhoneNum] = '111') 
OR
([t0].[CodeDescription] = 'Work') AND ([t1].[PhoneNum] = '222') )
GROUP BY [t1].[PersonID] HAVING COUNT(DISTINCT([t1].[PhoneNum]))=2

LINQ, который я сделал, примерно такой, как показано ниже:

 var ids = context.Code.Where(predicate);
            var rs = from r in ids
                     group r by new { r.phonenumbers.person.PersonID} into g
                     let matchcount=g.Select(p => p.phonenumbers.PhoneNum).Distinct().Count()
                     where matchcount ==2
                     select new
                  {
                      personid = g.Key
                  };

К сожалению, приведенный выше LINQ НЕ генерирует правильный результат и фактически генерируется внутри SQL, показанного ниже. Кстати, этот сгенерированный запрос также читает ВСЕ строки (около 19592040) примерно 2 раза из-за СЧЕТОВ :( Это тоже большая проблема с производительностью. Пожалуйста, помогите / укажите мне правильное направление.

Declare @p0 VarChar(10)='phone'
Declare @p1 VarChar(10)='Home'
Declare @p2 VarChar(10)='111'
Declare @p3 VarChar(10)='Work'
Declare @p4 VarChar(10)='222'
Declare @p5 VarChar(10)='2'

SELECT [t9].[PersonID], (
    SELECT COUNT(*)
    FROM (
        SELECT DISTINCT [t13].[PhoneNum]
        FROM [dbo].[Code] AS [t10]
        INNER JOIN [dbo].[phonenumbers] AS [t11] ON [t11].[PhoneType] = [t10].[Code]
        INNER JOIN [dbo].[Person] AS [t12] ON [t12].[PersonID] = [t11].[PersonID]
        INNER JOIN [dbo].[phonenumbers] AS [t13] ON [t13].[PhoneType] = [t10].[Code]
        WHERE ([t9].[PersonID] = [t12].[PersonID]) AND ([t10].[codetype] = @p0) AND ((([t10].[codetype] = @p1) AND ([t11].[PhoneNum] = @p2)) OR (([t10].[codetype] = @p3) AND ([t11].[PhoneNum] = @p4)))
        ) AS [t14]
    ) AS [cnt]
FROM (
    SELECT [t3].[PersonID], (
        SELECT COUNT(*)
        FROM (
            SELECT DISTINCT [t7].[PhoneNum]
            FROM [dbo].[Code] AS [t4]
            INNER JOIN [dbo].[phonenumbers] AS [t5] ON [t5].[PhoneType] = [t4].[Code]
            INNER JOIN [dbo].[Person] AS [t6] ON [t6].[PersonID] = [t5].[PersonID]
            INNER JOIN [dbo].[phonenumbers] AS [t7] ON [t7].[PhoneType] = [t4].[Code]
            WHERE ([t3].[PersonID] = [t6].[PersonID]) AND ([t4].[codetype] = @p0) AND ((([t4].[codetype] = @p1) AND ([t5].[PhoneNum] = @p2)) OR (([t4].[codetype] = @p3) AND ([t5].[PhoneNum] = @p4)))
            ) AS [t8]
        ) AS [value]
    FROM (
        SELECT [t2].[PersonID]
        FROM [dbo].[Code] AS [t0]
        INNER JOIN [dbo].[phonenumbers] AS [t1] ON [t1].[PhoneType] = [t0].[Code]
        INNER JOIN [dbo].[Person] AS [t2] ON [t2].[PersonID] = [t1].[PersonID]
        WHERE ([t0].[codetype] = @p0) AND ((([t0].[codetype] = @p1) AND ([t1].[PhoneNum] = @p2)) OR (([t0].[codetype] = @p3) AND ([t1].[PhoneNum] = @p4)))
        GROUP BY [t2].[PersonID]
        ) AS [t3]
    ) AS [t9]
WHERE [t9].[value] = @p5

Спасибо!

Ответы [ 2 ]

0 голосов
/ 15 мая 2010

Drats!Похоже, ошибка была на моей стороне (принцип GIGO!)

В моем ORM я создал ассоциации справа налево, а не наоборот.Я думаю, что это была проблема.

Единственная проблема, которая осталась сейчас, заключается в том, что каким-то образом LINQ генерирует один INNER JOIN дважды, и это удерживает окончательный результат для правильного получения.Если я закомментирую это в сгенерированном sql, я получу правильный результат.Это единственная проблема сейчас, и я думаю, я открою новый вопрос для этого.Спасибо за ваше время!

0 голосов
/ 15 мая 2010

Я думаю, что проблема может быть new { r.phonenumbers.person.PersonID}.

Почему вы обновляете новый объект здесь, а не просто группируете по r.phonenumbers.person напрямую? new {} каждый раз будет другим объектом, который никогда не будет группироваться.

После группировки по человеку я бы Select a group => new {person = group.person, phoneNumbers = group.person.phonenumbers} и затем проверил, сколько у них телефонных номеров, а затем окончательный прогноз.

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