我有以下功能:
public List<DTO.ArticleDTO> GetRecentArticles(int portalID, int moduleID, int domainID, int rootKnowledgeTypeID, int count)
{
var articles =
(from
article in _Context.Articles.LatestArticles(_Context.ArticleVersions, portalID, moduleID)
where _GetRootDomainsForArticle(article.ArticleID, article.Version, rootKnowledgeTypeID).Contains(domainID)
orderby article.UpdatedOn descending
select new ArticleDTO
{
ArticleID = article.ArticleID,
Title = article.Title,
Summary = article.Introduction,
Content = article.Content,
UpdatedOn = article.UpdatedOn,
Version = article.Version,
KnowledgeTypeText = (from
category in _Context.Categories
join
categoryVersion in _Context.ArticleCategoryVersions
on
category.CategoryID equals categoryVersion.CategoryID
where
categoryVersion.Version == article.Version &&
categoryVersion.ArticleID == article.ArticleID &&
category.ParentID == rootKnowledgeTypeID
select
category.Name
).First()
});
return articles.Take(count).ToList();
}
我要做的是获取属于根类别(域ID)的所有文章。类别被视为域/子域,每篇文章可以属于一个或多个域和子域。所以这就是我在上面的linq查询的where子句中使用以下方法的原因。
private IQueryable<int> _GetRootDomainsForArticle(int articleID, int version, int rootKnowledgeTypeID)
{
return from c in _Context.Categories
join cv in _Context.ArticleCategoryVersions on c.CategoryID equals cv.CategoryID
where cv.ArticleID == articleID
where cv.Version == version
where c.ParentID == null
where c.CategoryID != rootKnowledgeTypeID
select c.CategoryID;
}
我得到的错误是:“类型'System.Linq.IQueryable`1 [System.Int32]'不支持比较运算符。”
我认为是因为延迟执行,但我不太明白正确的方法。
修改:
基于@SivaGopal评论我将查询从_GetRootDomainsForArticle移动到主查询的一部分并且它有效:
public List<DTO.ArticleDTO> GetRecentArticles(int portalID, int moduleID, int domainID, int rootKnowledgeTypeID, int count)
{
var articles =
(from
article in _Context.Articles.LatestArticles(_Context.ArticleVersions, portalID, moduleID)
where (from c in _Context.Categories
join cv in _Context.ArticleCategoryVersions on c.CategoryID equals cv.CategoryID
where cv.ArticleID == article.ArticleID
where cv.Version == article.Version
where c.ParentID == null
where c.CategoryID != rootKnowledgeTypeID
select c.CategoryID).Contains(domainID)
orderby article.UpdatedOn descending
select new ArticleDTO
{
ArticleID = article.ArticleID,
Title = article.Title,
Summary = article.Introduction,
Content = article.Content,
UpdatedOn = article.UpdatedOn,
Version = article.Version,
KnowledgeTypeText = (from
category in _Context.Categories
join
categoryVersion in _Context.ArticleCategoryVersions
on
category.CategoryID equals categoryVersion.CategoryID
where
categoryVersion.Version == article.Version &&
categoryVersion.ArticleID == article.ArticleID &&
category.ParentID == rootKnowledgeTypeID
select
category.Name
).First()
});
return articles.Take(count).ToList();
}
我对Linq的有限理解让我相信,人们可以将查询分解为一种方法作为查询组合的形式,从而使其可重用。似乎并非如此,但肯定必须有一种方法可以做到这一点,因为它会大大减少代码,特别是在经常重复使用部分查询的情况下。
答案 0 :(得分:0)
尝试更多地分割你的函数,长而深的Linq方法可以工作,但它对于可读性并不是那么好,并且可能会引入你正在讨论的这类错误。我还没有对此进行测试,但它应该有助于解决您的问题:
public List<DTO.ArticleDTO> GetRecentArticles(int portalID, int moduleID, int domainID, int rootKnowledgeTypeID, int count)
{
var allArticles = _Context.Articles.LatestArticles(_Context.ArticleVersions, portalID, moduleID);
var filteredArticles = new List<DTO.ArticleDTO>();
foreach (DTO.ArticleDTO article in allArticles)
{
var domains = _GetRootDomainsForArticle(article.ArticleID, article.Version, rootKnowledgeTypeID);
if (domains.Contains(domainID)
{
filteredArticles.Add(article);
}
}
var articles = filteredArticles.OrderBy(article.UpdatedOn).Descending().Select(article => new DTO.ArticleDTO {
ArticleID = article.ArticleID,
Title = article.Title,
Summary = article.Introduction,
Content = article.Content,
UpdatedOn = article.UpdatedOn,
Version = article.Version,
KnowledgeTypeText = (from category in _Context.Categories
join categoryVersion in _Context.ArticleCategoryVersions
on category.CategoryID equals categoryVersion.CategoryID
where
categoryVersion.Version == article.Version &&
categoryVersion.ArticleID == article.ArticleID &&
category.ParentID == rootKnowledgeTypeID
select
category.Name
).First()
}).Take(count).ToList();
}
你也绝对需要返回IQueryable&lt;&gt;你的_GetRootDomainsForArticle函数?如果你能逃脱它,我会尝试返回IEnumerable&lt;&gt;代替。
幸