帮助使用LINQ选择与数组内链接表上的所有元素匹配的所有元素

时间:2010-10-20 12:12:36

标签: linq-to-sql

这有点奇怪所以我会先用简单的英语解释它。我有三张桌子。

TBL_PROFILE

TBL_LANGUAGES

TBL_LANGUAGES_LINK

其中关系是TBL_PROFILE - > TBL_LANGUAGE_LINK< - TBL_LANGUAGES

因此,如果一个人说3种语言,他们将在TBL_LANGUAGE_LINK中有三个条目。

基本上我传递了一个字符串数组的语言ID,我需要选择所有说明 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;

(仅供参考''语言'是一个字符串数组)

对我而言,这似乎是合乎逻辑的:“选择所有配置文件,其中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 :(得分:0)

试试这个。

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字段进行比较的事实。

答案 1 :(得分:0)

令人怀疑它是最有效的方法,但它返回的语言表中的语言与所提供的数组中的所有元素完全匹配。它还排除了仅符合原始目标的某些标准的元素。基本上我现在开始使用一整套配置文件并在我去的时候修剪元素。

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);
}

更好的方法仍然会受到赞赏!

答案 2 :(得分:0)

我认为以下查询可行。 您可以将语言数组加入语言表,如下所示。 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;