我首先在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
任何人都可以建议我需要使用的查询来检索以实现此结果吗?
答案 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。也许这应该是一个评论,但我还没有特权评论,所以如果我滥用这个网站,请告诉我应该遵循的正确方法。