Оператор Linq-to-SQL WHERE IN возвращает больше, чем нужно - PullRequest
1 голос
/ 28 февраля 2012

Хорошо, я пытаюсь создать частичное представление и контроллер, задачей которого является выбор и отображение списка аксессуаров для любого продукта, который в данный момент просматривается в родительском представлении.

База данных, с которой я снова работаю, хранит эту информацию в поле, отформатированном в виде списка через запятую, например:

productnr,productnr2,productnr3,productnr4

Поэтому я использую следующий код для извлечения этого списка ииспользуйте его для запуска эквивалента оператора SQL WHERE IN:

[ChildActionOnly]
public ActionResult _ListAccessories(string Artnr)
{
    var List = (
        from ArtTbl in db.ArtTbl
        where ArtTbl.ArticleNr == Artnr
        select ArtTbl.AccessoryList)
        .SingleOrDefault();

    var AccList = customFunctions.Accessories(text);

    var AccQuery = 
        from Art in db.ArtTbl
        where AccList.Contains(ArtTbl.ArticleNr)
        select new AccessoryList
        {
            Artnr = ArtTbl.ArticleNr,
            Name = ArtTbl.Namefield_1,
        };

    return PartialView(AccQuery);
}

Функция в переменной AccList преобразует первую строку в приведенный ниже результат.Я сделал это, потому что во всех примерах, которые я видел, использовался такой синтаксис, функция, кажется, работает правильно, как я уже тестировал, отправив ее в виде viewBag в представление, просто чтобы убедиться, что он выглядит правильно:

"productnr", "productnr2", "productnr3", "productnr4"

Вот так выглядит модель AccessoryList, просто очень простая модель:

public class AccessoryList 
{
    public string Artnr { get; set; }
    public string Name { get; set; }

    public AccessoryList()
    {
    }
}

Теперь этот код работает, но проблема в том, что он слишком велик, если у меня есть номер продукта всписок с надписью «AP500W», затем он также вернет «AP500» или просто «500».Это проблема, поскольку она должна возвращать только точное совпадение.

Ответы [ 2 ]

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

Причина, по которой у вас возникают проблемы, начинается и заканчивается так:

База данных, с которой я снова работаю, хранит эту информацию в поле отформатированный в виде списка через запятую

LINQ переводит это в оператор SQL, который обрабатывает значение всего поля как единый объект, поскольку является отдельным объектом. Когда Contains() вычисляется, он просто ищет совпадающие значения подстроки. Вот почему AP500 и 500 соответствуют AP500W.

Поскольку вы действительно пытаетесь сделать эквивалент WHERE IN (...), вам необходимо преобразовать MVA (многозначный атрибут) в набор различных значений.

Запрос работает в вашем примере, когда вы отправляете пакет просмотра отдельных значений строки :

"productnr", "productnr2", "productnr3", "productnr4"

Значение вашей базы данных на самом деле значение одной строки :

"productnr, productnr2, productnr3, productnr4"

Разница тонкая, но очень важная. Обратите внимание, что во втором примере есть только одна строка данных , которая действует как одно значение.

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

Деннис,

Я знаю, что следующее точно не ответит на вашу проблему.Тем не менее, это может приблизить вас к решению.В вашем примере вы говорите:

where AccList.Contains(ArtTbl.ArticleNr)

, поэтому вы получаете групповые результаты для набора результатов.Один из способов смягчить это - изучить только переднюю часть строки результата:

where AccList.StartsWith(ArtTbl.ArticleNr)

, на которую можно даже взглянуть (хотя я уверен, что это не сработает):

where AccList.Any(x => x.StartsWith(ArtTbl.ArticleNr))

в приведенном выше случае вы получите результаты для 'AP50', 'AP500' и т. Д., И т. Д. Может потребоваться дальнейшее расследование (сейчас я не работаю с компилятором, поэтому не могу проверить, работает ли вышеуказанное какожидается или нет: -)).

...