Динамический обратный слэш linq в предложении where
Я использую System.Linq.Dynamic для запроса сущностей с динамическими выражениями "где". Я запрашиваю объект, который имеет свойство "newValue" типа строки. Примерное значение будет следующим: "{\"ProcessId\":764, \"ProcessLength\":1000}". Я не могу использовать ==, потому что я хочу найти все попадания, где свойство содержит "ProcessId:764", независимо от остальной части строки. Дело в том, что сохраненная строка содержит escape-знак "\" и двойные кавычки, и я не могу понять, что именно должно нравиться..
dbContext.Processes.Where("@newValue.Contains(\"ProcessId\":764\")")
приносит ошибку, однако dbContext.Processes.Where("@newValue.Contains(\":764\")")
работает правильно. Я предполагаю, что это должно быть что-то с обратной косой чертой или двойными кавычками в моем запросе, но я не могу понять это самостоятельно..
2 ответа
Здесь следует отметить две вещи:
Если вы знаете во время компиляции столбец, который должен быть запрошен (т.е.
newValue
), просто используйте стандартный Linq:var list = items.Where(i => i.NewValue.Contains("904")).ToList()
,Если вы действительно хотите использовать dyanmic Linq, вам нужно подать заявку
Where
на каком-то столбце, напримерWhere("SomeColumn.Contains("something")")
, или жеWhere("SomeColumn.Contains(@0)", new string[] {"something"})
,Итак, в вашем случае это должно работать:
items.Where("newValue.Contains(\"904\")")
,дела
Where("@newValue.Contains("something")")
на самом деле не имеет смысла, так как@newValue
будет проанализирован как строковый литерал. Смотрите также этот комментарий на похожий вопрос.
Вот краткий пример:
public static void Main(string[] args)
{
var items = new []
{
new { Id = "1", Title = "ProcessId: 123"},
new { Id = "4", Title = "ProcessId: 456"},
new { Id = "7", Title = "ProcessId: 789"},
}.ToList();
// returns null, because the string "Title" doesn't contain the string "7"
var res1 = items.Where("@0.Contains(\"7\")", new string[] {"Title"}).FirstOrDefault();
// works - returns the 3rd element of the array
var res2a = items.Where("Title.Contains(@0)", new string[] {"ProcessId: 789"}).FirstOrDefault();
var res2b = items.Where("Title.Contains(\"ProcessId: 789\")").FirstOrDefault();
}
@HeyJude Спасибо за усилия, но я все еще не могу заставить их работать. Это как-то пошло не так, и теперь я не могу даже выбрать правильные строки, дающие только номер ProcessId..
Позвольте мне дать вам более подробное описание моей установки. В базе данных есть таблица со столбцом "NewValue", я использую этот столбец для хранения json-строки текущего (на момент создания строки в таблице) представления некоторого объекта, например объекта Process. Таким образом, в столбце хранится, например, строка {"ProcessId": 904, "ProcessLength": 1000}. Чтобы получить эти данные из базы данных, я создаю коллекцию записей таблицы: var items = (from l in db.JDE_Logs
join u in db.JDE_Users on l.UserId equals u.UserId
join t in db.JDE_Tenants on l.TenantId equals t.TenantId
where l.TenantId == tenants.FirstOrDefault().TenantId && l.Timestamp >= dFrom && l.Timestamp <= dTo
orderby l.Timestamp descending
select new //ExtLog
{
LogId = l.LogId,
TimeStamp = l.Timestamp,
TenantId = t.TenantId,
TenantName = t.TenantName,
UserId = l.UserId,
UserName = u.Name + " " + u.Surname,
Description = l.Description,
OldValue = l.OldValue,
NewValue = l.NewValue
});
, Затем я запрашиваю его, чтобы найти соответствующие строки для данного номера ProcessId, например query = "@NewValue.Contains(\"904,)\")";
items = items.Where(query);
Это должно извлечь все записи, где столбец NewValue содержит строку запроса, но это не работает. Он компилируется и "работает", но данные не извлекаются или извлекаются, это только те записи, где 904 появляется позже в строке. Звучит глупо, но это то, что есть.
Как должна выглядеть строка запроса для получения всех записей, содержащих "ProcessId":904
?