Linq: добавление дополнительной фразы 'Where' дает случайные результаты - PullRequest
2 голосов
/ 28 февраля 2012

Я новичок в использовании Linq, и многое из этого совершенно запутанно.

Я скачал и использовал библиотеку LinqFlickr из http://linqflickr.codeplex.com. Я думаю, однако, что это всего лишь мое отсутствие понимания о 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 Ответ

2 голосов
/ 28 февраля 2012

Ваш запрос выглядит нормально.Я предполагаю, что это ошибка (или неинтуитивное поведение при разработке) в Афине, где дополнительное «цепочечное» предложение 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...