Преобразование левого внешнего присоединения к структуре сущности

StackOverflow https://stackoverflow.com/questions/9500103

  •  14-11-2019
  •  | 
  •  

Вопрос

Вот запрос SQL, который я хочу преобразовать в EF4.3

        command = database.GetSqlStringCommand(@"
                                select 
                                    H.AUTHENTICATION_ID, 
                                    USERNAME, 
                                    PERMISSIONS,
                                    ORGANIZATION_IDENTIFIER, 
                                    O.ORGANIZATION_ID 
                                from 
                                    AUTHENTICATION H 
                                        left join [AUTHORIZATION] T on H.AUTHENTICATION_ID=T.AUTHENTICATION_ID 
                                        join ORGANIZATION O on O.ORGANIZATION_ID = T.ORGANIZATION_ID
                                order by H.AUTHENTICATION_ID");
.

Вот лучший linq, который я мог бы придумать:

        var query = from h in context.Authentications
            join t in context.Authorizations on h.AuthenticationId equals t.Authentications.AuthenticationId 
            join o in context.Organizations on t.Organizations.OrganizationId equals o.OrganizationId
            orderby
            h.AuthenticationId
            select new
            { AUTHENTICATION_ID = (Int16?)h.AuthenticationId,
                h.Username,
                t.Permissions,
                o.OrganizationIdentifier,
                OrganizationID = (Int16?)o.OrganizationId
            };
.

Я знаю, что мне нужно объединить мой первый присоединение (между авторизациями и аутентификациями), позволяет сказать x и применить defalfulty, но не может разглядеть синтаксис.

<Сильные> Редактировать: Изображение для разъяснения: Модель данных

Любая помощь будет высоко оценена.С уважением.

Это было полезно?

Решение

Базовый синтаксис для «левого присоединения» в LINQ подобно следующему:

from x in table1
join y in table2 on x.id equals y.id into jointable
from z in jointable.DefaultIfEmpty()
select new
{
  x.Field1, 
  x.Field2,
  x.Field3,
  Field4 = z == null ? 0 : z.Field4
};
.

В вашем случае я немного запутался, потому что отношения сущности, которые вы, кажется, используете в вашем LINQ, не соответствуют тем, что подразумевается вашим SQL;Здесь отношения здесь нулевой или один, нулевой или много, один к одному и т. Д.?В частности, вы делаете это:

from h in context.Authentications
join t in context.Authorizations on h.AuthenticationId equals t.Authentications.AuthenticationId
.

Но ваш SQL подразумевает, что «аутентификация» является родительским здесь с нолью или более «авторизацией» детьми, а не наоборот, что было бы больше похоже на:

from h in context.Authentications
from t in h.Authorizations.DefaultIfEmpty()
.

Если вы можете дать нам лучшее представление о модели данных и какие данные вы ожидаете выйти из этого, мы можем легче объяснить, как этот запрос будет смотреть в LINQ.Предполагая, что ваши отношения соответствуют тому, что подразумевается SQL, вы должны быть в состоянии получить то, что вы хотите использовать следующие запросы LINQ:

var query = from h in context.Authentications
            from t in h.Authorizations.DefaultIfEmpty()
            select new
            {
                h.AuthenticationId,
                h.Username,
                Permissions = t == null ? null : t.Permissions,
                Organizations = t == null ? new EntitySet<Organization>() : t.Organizations
            };

var query2 = from x in query
             from o in x.organizations.DefaultIfEmpty()
             select new
             {
                 AUTHENTICATION_ID = (short?)x.AuthenticationId,
                 x.Username,
                 x.Permissions,
                 OrganizationIdentifier = o == null ? null : o.OrganizationIdentifier,
                 OrganizationID = o == null ? (short?)null : o.OrganizationID 
             };
.

Другие советы

Учитывая иностранные ключи, которые существуют в диаграмме вопроса, как насчет чего-то вроде этого?

var query = from a in context.Authentications
            select new
            {
                a.AuthenticationID,
                a.Username,
                a.Authorisations.Permissions ?? false,
                a.Authorisations.Organisations.OrganisationIdentifier ?? 0
                a.Authorisations.Organisations.OrganisationID ?? 0
            };
.

Я пошел вперед и переместил весь запрос в сохраненную процедуру в базе данных.Это решает проблему, избегая LINQ и ObjectBuilder в первую очередь.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top