Linq:添加额外'where'条款给​​出随机结果

时间:2012-02-28 15:04:34

标签: c# .net linq flickr

我是使用Linq的初学者,现在很多人都很困惑。

我从http://linqflickr.codeplex.com下载并使用了LinqFlickr库。但我认为这只是我对Linq缺乏了解。 LinqFlickr项目没有太多文档可供我继续使用。

如果我运行以下代码,如果用户名字符串为空,则运行正常并返回带有特定标记的照片。但如果有一个用户名,它应该优化特定用户以前的结果,而不是给我一堆随机照片。

            var photos = (from ph in context.Photos
                      where
                      ph.SearchMode == SearchMode.TagsOnly
                      && ph.SearchText == tag
                      && ph.PhotoSize == PhotoSize.Small
                      && ph.Extras == (ExtrasOption.Owner_Name |  ExtrasOption.Date_Taken)
                      select ph);

            if (username != "")
            {
                string personId = (from people in context.Peoples
                                where 
                                people.Username == username
                                select people.Id).First();
                photos = photos.Where(q => q.NsId == personId) ;
            }

            photos = photos.Take(10);

我尝试使用一些调试工具,如LinqPad和MetaLinq,但我无法用它们来解决它。

另外,我确定我的Linq查询可以在一个查询中进行,这将是很好的,但请解释它,以便Linq新手可以理解!

1 个答案:

答案 0 :(得分:2)

您的查询看起来很好。我的猜测是,这是一个在Athena中的错误(或不直观的设计行为),其中一个额外的“链式”where子句导致原始where子句被遗忘。

独立组装第二个查询(即一个大where子句中的所有约束)并检查这是否修复了问题。如果是这样,那肯定是API中的一个错误。您可以使用LINQKit动态地汇编和扩展where子句的谓词来解决此问题。以下是这可能的样子:

// Original predicate without userId constraint
Expression<Func<Photo, bool>> predicate = ph =>  
        ph.SearchMode == SearchMode.TagsOnly
     && ph.SearchText == tag
     && ph.PhotoSize == PhotoSize.Small
     && ph.Extras == (ExtrasOption.Owner_Name |  ExtrasOption.Date_Taken);

if (!string.IsNullOrEmpty(username)) 
{
    // Build the userId constraint into the predicate.

    var personId = (from people in context.Peoples
                    where  people.Username == username
                    select people.Id).First();

    // "And" combines the predicates
    // "Expand" removes the use of invocation expressions, which 
    // some LINQ providers have problems with.
    predicate = predicate.And(q => q.NsId == personId).Expand();
}

// Final result
var photos = context.Photos.Where(predicate).Take(10);