Использование LinQ для проверки того, содержит ли столбец значения с разделителями-запятыми [duplicate]

Это означает, что указанная переменная не указана ни на что. Я мог бы сгенерировать это так:

SqlConnection connection = null;
connection.Open();

Это вызовет ошибку, потому что, пока я объявил переменную «connection», она не указала ни на что. Когда я пытаюсь вызвать член «Open», для его устранения нет ссылки, и он будет вызывать ошибку.

Чтобы избежать этой ошибки:

  1. Всегда инициализируйте свои объекты, прежде чем пытаться что-либо с ними делать.
  2. Если вы не уверены, что объект имеет значение null, проверьте его с помощью object == null.

Инструмент Resharper JetBrains определит каждое место в вашем коде, которое имеет возможность ошибки нулевой ссылки, позволяя вам ввести нулевую проверку. Эта ошибка является источником ошибок номер один, IMHO.

3
задан Alon Gubkin 31 July 2009 в 12:01
поделиться

5 ответов

1) ToList () ваш запрос var

2) В сгенерированном списке за 1 шаг напишите свой запрос на сложение и разделение: он правильно выполнит

удачу

-2
ответ дан A B 31 August 2018 в 19:02
поделиться

Итак, вы ищете значение (из строки запроса) в столбце с разделителями пробелов в базе данных? И вы используете Split для запроса отдельных значений внутри базы данных?

(просто проверяя мои предположения ...)

string.Split не поддерживается таким образом ( в базе данных по данным столбца) - см. здесь поддерживаемые строковые операции . (обратите внимание, что string.Split явно явно не поддерживается).

Я ленив; когда я делит данные в базе данных (относительно редко), я всегда добавляю один и тот же разделитель к началу и концу данных; то я могу просто искать:

string searchFor = DELIMITER + searchValue + DELIMITER;
...
.Where(row => row.Value.Contains(searchFor));

Однако; в этом случае я ожидаю, что наиболее практичным вариантом может быть запись функции UDF, которая выполняет поиск в разделителе varchar (правильно обрабатывает первый / последний элемент) и выставляет UDF в контексте данных - затем используйте:

.Where(row => ctx.ContainsValue(row.Value, searchValue)); // ContainsValue is our UDF

Или - нормализовать данные ...

.Where(row => row.Values.Any(s=>s.Value == searchValue));
4
ответ дан Marc Gravell 31 August 2018 в 19:02
поделиться

Во-первых, я бы избежал хранения данных с разделителями в базе данных. Как вы узнали, это может сделать запросы к базе данных и т. Д. Неудобными.

Если у вас ограниченное количество категорий, я бы попросил ответа Джо для простоты, иначе, добавив некоторые детали к подходу Марка.

  1. Создайте UDF с разделенным стилем, для SQL Server я использую:

CREATE FUNCTION FN_CHARLIST_TO_TABLE
 (@list      nvarchar(MAX),
  @delimiter nchar(1) = N',')
RETURNS @tbl TABLE (listpos int IDENTITY(1, 1) NOT NULL,
              str     varchar(4000)      NOT NULL,
              nstr    nvarchar(2000)     NOT NULL) AS
/*                
  Comments:
        - Takes a CSV string, and creates a table of data from this
        - Each item takes one row in the following format
            listpos - the index of the item in the string (effectively a row number in the output)
            str - The value, as VARCHAR
            nstr - The value, as NVARCHAR

        - This function is a direct extract from http://www.sommarskog.se/arrays-in-sql-2005.html#iter-list-of-strings
Usage:
    SELECT * 
    FROM  t 
    JOIN FN_CHARLIST_TO_TABLE('a,b,c,1,2,3', ',') list
    ON t.Name = list.str        
*/
BEGIN
   DECLARE @endpos   int,
       @startpos int,
       @textpos  int,
       @chunklen smallint,
       @tmpstr   nvarchar(4000),
       @leftover nvarchar(4000),
       @tmpval   nvarchar(4000)

   SET @textpos = 1
   SET @leftover = ''
   WHILE @textpos  0
      BEGIN
     SET @tmpval = ltrim(rtrim(substring(@tmpstr, @startpos + 1,
                         @endpos - @startpos - 1)))
     INSERT @tbl (str, nstr) VALUES(@tmpval, @tmpval)
     SET @startpos = @endpos
     SET @endpos = charindex(@delimiter COLLATE Slovenian_BIN2,
                 @tmpstr, @startpos + 1)
      END

      SET @leftover = right(@tmpstr, datalength(@tmpstr) / 2 - @startpos)
   END

   INSERT @tbl(str, nstr)
      VALUES (ltrim(rtrim(@leftover)), ltrim(rtrim(@leftover)))
   RETURN
END

  1. Добавьте это в свой DBML-файл
  2. Запросить базу данных, соответствующим UDF

var catergories = from cat in _datacontext.Categories
                  from keyword in _datacontext.FN_CHARLIST_TO_TABLE(cat.Keywords, ' ')
                  where keyword.str == context.Request.QueryString["q"]
                  select cat;

Затем будет выполняться запрос на основе базы данных.

0
ответ дан MattH 31 August 2018 в 19:02
поделиться

Вероятно, что context.Request.QueryString["q"] возвращает строковый массив вместо одной строки. Это связано с тем, что URL-адрес может содержать несколько параметров с тем же именем.

Если вы уверены, что в запросе всегда есть только один параметр с именем q, вы можете изменить свой код на это: context.Request.QueryString["q"].SingleOrDefault().

0
ответ дан Ronald Wildenberg 31 August 2018 в 19:02
поделиться
  • 1
    Просто проверено - нет. Он возвращает "q1, q2, q3, q4, q5" как строку, а не массив. – Arnis Lapsa 31 July 2009 в 12:10
  • 2
    HttpRequest.QueryString - это NameValueCollection. – Alon Gubkin 31 July 2009 в 12:12
  • 3
    Indexer NameValueCollection возвращает строку -_- – Arnis Lapsa 31 July 2009 в 12:12
  • 4
    Ах хорошо. Тогда мой ответ действительно не помогает ... – Ronald Wildenberg 31 July 2009 в 12:13
  • 5
    На самом деле - я думал то же самое. Но проверено перед публикацией. :) – Arnis Lapsa 31 July 2009 в 12:14

string.split не поддерживается в LINQ-to-SQL.

Есть легкое исправление. Выберите все данные и выполните фильтрацию в клиенте. Это может быть не очень эффективным в зависимости от количества категорий.

var category = 
    _dataContext.Categories.ToList()
    .Where<Category>(p => p.Keywords.Split(' ').Contains<string>(context.Request.QueryString["q"])).First();

Вызов .ToList() заставит перечисление всех категорий из вашего источника данных, а последующие операции будут выполняться в клиентском коде.

3
ответ дан Winston Smith 31 August 2018 в 19:02
поделиться
  • 1
    Чтение всей таблицы обратно клиенту - почти всегда плохая идея. Есть случаи, когда он работает, но они являются строгим меньшинством. – Marc Gravell♦ 31 July 2009 в 12:38
  • 2
    Действительно, это может быть огромный успех, но нужно взвесить это против общепринятого мнения о том, что предварительная оптимизация также плоха. Помимо крупномасштабных проектов, в которых это было бы проблемой, существует, вероятно, множество небольших веб-приложений, где производительность, связанная с этим сценарием, была бы тривиальной. Я думаю, это просто сводится к здравому смыслу. – Winston Smith 31 July 2009 в 13:07
Другие вопросы по тегам:

Похожие вопросы: