2009-10-09 1 views
1

Я пытаюсь получить запрос, который будет искать несколько тегов. Теги основаны на db, и я связал их с сущностью с помощью таблицы соединений. Если я ищу с 1 тегом, я получаю правильные результаты, но если я ищу с 2 тегами, я получаю только сущности, соответствующие второму тегу.LINQ: multiple В каких случаях используется только последний?

Вот C# код, который строит IQueryable:

var awTable = db.Artworks.Where(aw => true); //default get all 

    awTable = awTable.Where(aw => (bool)aw.IsArtworkVisible ); 


    foreach (SearchTag tagToMatch in tagList) 
       { 

        awTable = awTable.Where(aw => aw.ArtworkName.Contains(tagToMatch.SearchTagText) 
               || db.SearchTag_x_Artworks.Where(stxa => stxa.SearchTagID == tagToMatch.SearchTagID) 
               .Select(stxa => stxa.ArtworkID).Contains(aw.ArtworkID)); 


       } 

Вот результирующий SQL, который, если я подключить его в окно запроса и задать значения параметров, включает в себя как где положения и возвращает правильный список сущностей. (WTF!?!?)

{SELECT [t0].[ArtworkID], [t0].[ArtworkName], ... [t0].[MediumID] 
FROM [dbo].[Artworks] AS [t0] 
WHERE ((EXISTS(
    SELECT NULL AS [EMPTY] 
    FROM [dbo].[SearchTag_x_Artwork] AS [t1] 
    WHERE ([t1].[ArtworkID] = [t0].[ArtworkID]) AND ([t1].[SearchTagID] = @p0) 
    )) OR ([t0].[ArtworkName] LIKE @p1)) AND ((EXISTS(
    SELECT NULL AS [EMPTY] 
    FROM [dbo].[SearchTag_x_Artwork] AS [t2] 
    WHERE ([t2].[ArtworkID] = [t0].[ArtworkID]) AND ([t2].[SearchTagID] = @p2) 
    )) OR ([t0].[ArtworkName] LIKE @p3)) AND (([t0].[IsArtworkVisible]) = 1) 
} 

Это своего рода растерзание, любые советы приветствуются. Благодарю.

+1

Что действительно заставляет вас задуматься, почему вы делаете некоторые вещи: 'var awTable = db.Artworks.Where (aw => true); // default get all' ... wat – JustLoren

+0

Я попробовал уйти из инструкции if для ясности: var awTable = db.Artworks.Where (aw => true); if (! IsAuthenticated) { awTable = awTable.Where (aw => (bool) aw.IsArtworkVisible); } –

ответ

2

Я думаю, ваша проблема связана с ручками пути C# захваченных переменных в затворах как ваша лямбда-выражение.

Ваш захват той же переменной tagToMatch. Пожалуйста, попробуйте следующее:

foreach (SearchTag tagToMatch in tagList) 
    { 
     SearchTag localTagToMatch = tagToMatch; 
     awTable = awTable.Where(aw => aw.ArtworkName.Contains(localTagToMatch .SearchTagText) 
               || db.SearchTag_x_Artworks.Where(stxa => stxa.SearchTagID == localTagToMatch .SearchTagID) 
               .Select(stxa => stxa.ArtworkID).Contains(aw.ArtworkID)); 
    } 

Пожалуйста, прочтите The Beauty of Closures Джон тарелочкам.

+0

Ding ding ding! Святое дерьмо, которое работает! Благодаря! Спасибо за ссылку, так как это не совсем очевидно, что что-то происходит, как и в последнем SearchTag, где все элементы lambdas получают значения параметров, поэтому мне нужно будет прочитать об этом. –

1
var awTable = db.Artworks.Where(aw => (bool)aw.IsArtworkVisible); //the first was unnecessary 

foreach (SearchTag tagToMatch in tagList) 
{ 
    awTable = awTable.AndAlso(aw => 
     aw.ArtworkName.Contains(tagToMatch.SearchTagText) || 
     db.SearchTag_x_Artworks.Where(stxa => stxa.SearchTagID == tagToMatch && stxa.ArtworkID == aw.ArtworkID); 
} 
+0

Хммм, моя версия LINQ не имеет AndAlso. Я должен буду искать это и посмотреть, смогу ли я загрузить его. –

Смежные вопросы