Помогите с помощью LINQ выбрать все элементы, которые соответствуют всем элементам в связанной таблице, которые находятся внутри массива - PullRequest
0 голосов
/ 20 октября 2010

Это немного странно, поэтому я сначала попытаюсь объяснить это простым языком. У меня есть три стола.

TBL_PROFILE

TBL_LANGUAGES

TBL_LANGUAGES_LINK

где отношение TBL_PROFILE -> TBL_LANGUAGE_LINK <- TBL_LANGUAGES </p>

поэтому, если человек говорит на 3 языках, у него будет три записи в TBL_LANGUAGE_LINK.

Обычно я передаю строковый массив идентификаторов языков, и мне нужно выбрать все профили, которые говорят на ALL языках в этом массиве, а не только один из них.

Вот что я придумала

from p in db.TBL_PROFILEs                        
where p.ACTIVE == true 
   && p.TBL_LANGUAGES_LINKs.All(x => languages.Contains(x.LANGUAGE_ID.ToString())) == true
select p;

(FYI 'languages' - это массив строк)

Мне кажется, это логично: s "Выбрать все профили, в которых все элементы в languages_link входят в массив языков"

По какой-то причине я получаю все записи в TBL_PROFILE, которые мне сложно объяснить.

Я приложил сгенерированный LINQ SQL ниже для дополнительной информации (извиняюсь, если ответ очевиден - мои навыки SQL не самые лучшие)

    {SELECT [t0].[PROFILE_ID], [t0].[USER_ID].........

    FROM [dbo].[TBL_PROFILE] AS [t0]
    WHERE ([t0].[ACTIVE] = 1) AND (NOT (EXISTS(
    SELECT NULL AS [EMPTY]
    FROM [dbo].[TBL_LANGUAGES_LINK] AS [t1]
    WHERE ((
        (CASE 
            WHEN (CONVERT(NVarChar,[t1].[LANGUAGE_ID])) IN (@p0, @p1) THEN 1
            ELSE 0
         END)) = 0) AND ([t1].[PROFILE_ID] = [t0].[PROFILE_ID])
    )))
}

Любая помощь или совет с благодарностью:)

Ответы [ 3 ]

0 голосов
/ 20 октября 2010

Сомнительно, это самый эффективный способ сделать это, но он возвращает профили, у которых есть языки в таблице языков, которые точно соответствуют всем элементам в предоставленном массиве.Это также исключает элементы, которые соответствуют только некоторым критериям, которые были первоначальной целью.По сути, теперь я начинаю с полного набора профилей и обрезки элементов по ходу работы.

var query = from p in db.TBL_PROFILEs
            where p.ACTIVE == true
            select p;


foreach (int language in languages)
{
     query = query.Where(p => p.TBL_LANGUAGES_LINKs.Where(
                                               x =>
                                               x.LANGUAGE_ID == language)
                                               .Count() == 1);
}

Лучший способ сделать это все равно будет оценен!

0 голосов
/ 05 февраля 2013

Я думаю, что следующий запрос будет работать. Вы можете внутренне присоединить массив языков к таблице языков следующим образом. Linq позволяет вам сделать это. См:

int[] languages = // populate languages
var query = from p in db.TBL_PROFILE
            join link in db.TBL_Languages_Links on link.ProfileID equals p.ProfileID
            join lang in db.TBL_LANGUAGES on link.LanguageID equals lang.LanguageID
            join arrlang in languages on lang.LanguageName equals arrlang
            where p.ACTIVE == true
            select p;
0 голосов
/ 20 октября 2010

попробуйте это.

from p in db.TBL_PROFILEs                        
where p.ACTIVE == true 
join l in db.TBL_Languages_Links on
p.ProflieID equals l.ProflieID
where languages.Contains(l=>l.Language_ID.ToString())
select p;

ответ основан на множестве предположений о внешних ключах таблицы и факте, что вы сравниваете строки с полями ID.

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