Проверьте, содержит ли значение String любое число, используя выражение Lambda
У меня есть запрос SQL
, который извлекает только имена, не содержащие никакого числа:
...
WHERE Name NOT LIKE '%[0-9]%'
С другой стороны, при попытке использовать этот запрос в Lambda Expression
с различными комбинациями, как показано ниже, ни один из них не работает:
.Where(m => !m.EmployeeName.Contains("%[0-9]%")
или
.Where(m => !m.EmployeeName.Contains(".*[0-9].*")
Как использовать метод NOT LIKE
в Lambda Expression
?
Обновление: Мое выражение лямбда показано ниже:
return Json(db.TEmployees
.Where(m => m.Status == Enums.Status.Active)
.AsEnumerable()
.Where(m => !Regex.IsMatch(m.EmployeeName, ".*[0-9].*"))
.Select(m => new { ID = m.EmployeeID, EmployeeName = m.EmployeeName }),
JsonRequestBehavior.AllowGet);
Ответы
Ответ 1
Насколько я знаю, вы не можете применять регулярное выражение в Linq к Entities. То, что я рекомендую сделать, это если у вас есть другие условия, вызовите метод Where
, используя их сначала, а затем вызовите AsEnumerable
для работы с Linq to Object, который позволяет использовать регулярные выражения, чтобы вы могли применить необходимое условие:
var query= context.YourDbSet.Where(...)
.AsEnumerable()
.Where(m => !Regex.IsMatch(m.EmployeeName, @"\d"));
Или вы также можете сделать следующее:
var query= context.YourDbSet.Where(...)
.AsEnumerable()
.Where(e=>e.!EmployeeName.Any(char.IsDigit));
Обновление:
Третье решение может использовать метод DbSet.SqlQuery для выполнения вашего необработанного SQL-запроса:
var query= context.YourDbSet.SqlQuery("SELECT * FROM Table WHERE Name NOT LIKE '%[0-9]%'");
Перевод этого сценария будет следующим:
// This column names must match with
// the property names in your entity, otherwise use *
return Json(db.TEmployees.SqlQuery("SELECT EmployeeID,EmployeeName
FROM Employees
WHERE Status=1 AND Name NOT LIKE '%[0-9]%'"),
JsonRequestBehavior.AllowGet);// Change the value in the first condition for the real int value that represents active employees
Ответ 2
Попробуйте эту дополнительную информацию ссылка:
return Json(db.TEmployees
.Where(m => m.Status == Enums.Status.Active && !m.EmployeeName.Any(char.IsDigit))
.Select(m => new { ID = m.EmployeeID, EmployeeName = m.EmployeeName }).ToList(),
JsonRequestBehavior.AllowGet);
EDIT: Добавить ToList() в ответ json
Ответ 3
EF ограничен возможностью генерировать точный SQL, который вы хотите. Я не знаю конкретного выражения, которое будет генерировать шаблон [0-9]
в вашем предложении LIKE
.
Список Строковые функции
которые поддерживаются EF, документируются в MSDN. Ни один из них не может быть использован для определения того, содержит ли строка произвольную цифру или нет.
Некоторые другие варианты:
- Используйте точный SQL, который вы хотите на С#, и вызовите
ExecuteStoreCommand
- Возвращайте больше объектов, чем вам нужно из БД и фильтруйте в памяти, используя
AsEnumerable()
Эквивалентный SQL будет чем-то вроде
SELECT *
FROM TEmployees
WHERE Status = {code for active status}
AND Name NOT LIKE '%[0-9]%'
Ответ 4
Вы можете использовать Regex.IsMatch
.
yourEnumerable.Where(m => !Regex.IsMatch(m.EmployeeName, @"\d"));
Ответ 5
Единственное решение, использующее Linq-To-Entities, о котором я могу думать, это определить строковый массив и посмотреть, содержит ли ваша строка ни одно из них:
string[] digits = new { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
...Where(m => !digits.Any(m.EmployeeName.Contains(d));
Я могу представить, что это будет медленный запрос, хотя для больших наборов данных, поэтому я бы просто выполнил sql через EF.
Ответ 6
Нет общего решения LINQ to Entities.
Однако если вы нацеливаете базу данных Sql только, вы можете использовать SqlFunctions.PatIndex каноническую функцию следующим образом:
db.TEmployees
.Where(m => m.Status == Enums.Status.Active &&
SqlFunctions.PatIndex("%[0-9]%", m.EmployeeName) == 0)
//...