Динамический обратный слэш 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 ответа

Решение

Здесь следует отметить две вещи:

  1. Если вы знаете во время компиляции столбец, который должен быть запрошен (т.е. newValue), просто используйте стандартный Linq: var list = items.Where(i => i.NewValue.Contains("904")).ToList(),

  2. Если вы действительно хотите использовать 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?

Другие вопросы по тегам