Entity Framework Code First 左连接

3

DB Tables

我已经使用EF Code First创建了一个简单的数据库,但好像遇到了问题。

我想要查询DBContext以检索一个自定义对象CheckedTag,该对象将具有所有可用标签和一个布尔字段来表示是否选中。

Code First抽象出了多对多表格,但我似乎找不到正确的查询方法。

我尝试过

            var qry = from t in Db.Tags
                  from a in Db.Articles
                  where(a.Id == articleId) 
                  select new CheckedTag 
                         { 
                             Id = t.Id, 
                             Name = t.Name, 
                             PermanentUrl = t.PermanentUrl, 
                             Checked = t.Id == null ? false : true 
                         };

我已经在网上搜寻了几个小时。

如果articleId为0,则会检索所有标签,并将checked设置为false;如果articleId是现有文章的ID,则会返回所有标签,并将选中的标签设置为true。

请问有人可以建议我需要使用哪个查询来实现这个结果吗?

2个回答

4

如果我理解正确,你想获取特定文章(其ID为'articleId')的所有标签列表(不仅限于它已有的标签),并在它拥有该标签时将“Checked”设置为true,否则为false。如果是这样,这是我建议的查询:

var checkedTags= from t in Db.Tags
                 select new CheckedTag
                        {
                            Id = t.id,
                            Name = t.name,
                            PermanentUrl = t.PermanentUrl,
                            Checked = t.Articles.Any(a => a.Id == articleId)
                        };

希望这有所帮助 :) 编辑: 将“包含”替换为“任何”。感谢@Yakimych。

2
你走在正确的道路上,但是请使用 Any 而不是 Contains - Yakimych
谢谢你,Abdou和Yakimych,你们刚刚为我解决了一个头疼的问题 :) - Simon Hazelton

2
我建议在AbdouMoumen的答案上进行一些小改进。(在.Net 4和EF 4中测试过)
我使用SQL分析器检查了一下,语句“Checked = t.Articles.Any(...)”虽然可以得到正确的结果,但它生成的SQL代码稍微有些低效。
(注意:我的代码具有不同的实体名称,但完全相同的情况)
生成的代码如下:
    CASE WHEN ( EXISTS (SELECT 
    1 AS [C1]
    FROM [dbo].[LocationFeatures] AS [Extent2]
    WHERE ([Extent1].[FeatureID] = [Extent2].[FeatureID]) AND (1 = [Extent2].[LocationID])
)) THEN cast(1 as bit) WHEN ( NOT EXISTS (SELECT 
    1 AS [C1]
    FROM [dbo].[LocationFeatures] AS [Extent3]
    WHERE ([Extent1].[FeatureID] = [Extent3].[FeatureID]) AND (1 = [Extent3].[LocationID])
)) THEN cast(0 as bit) END AS [C1]

我通过将其更改为“Checked =(t.Articles.Any(...))?true:false”进行了测试,结果数据与稍微更好的SQL代码相同。

CASE WHEN ( EXISTS (SELECT 
    1 AS [C1]
    FROM [dbo].[LocationFeatures] AS [Extent2]
    WHERE ([Extent1].[FeatureID] = [Extent2].[FeatureID]) AND (1 = [Extent2].[LocationID])
)) THEN cast(1 as bit) ELSE cast(0 as bit) END AS [C1]

附言:也许这应该是一条评论,但我还没有评论的权限,如果我滥用了这个网站,请告知我应该遵循的正确方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接