实体框架代码第一个左连接

时间:2011-04-20 11:07:50

标签: entity-framework linq-to-entities many-to-many left-join ef-code-first

DB Tables

我首先在EF代码中创建了一个简单的数据库,但似乎遇到了问题。

我想要做的是,查询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用于现有文章,则将返回所有标签并且将checked标签设置为true

任何人都可以建议我需要使用的查询来检索以实现此结果吗?

2 个答案:

答案 0 :(得分:4)

如果我理解正确的话,你想得到一个特定的文章(有id'articleId),所有标签的列表(不仅仅是那些标签),并且如果它有一个“Checked”为true确实如此,否则就是假的。如果是这样,这是我建议的查询:

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。

答案 1 :(得分:2)

我建议对AbdouMoumen的回答略有改进。 (使用EF 4在.Net 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]

P.S。也许这应该是一个评论,但我还没有特权评论,所以如果我滥用这个网站,请告诉我应该遵循的正确方法。