Я не совсем уверен, что ваш вопрос здесь, но есть несколько вещей, которые могут помочь.
Во-первых, если вы пытаетесь найти что-то, что имеет только одно совпадение, или в сценарииесли вам нужна только одна вещь, тогда вы должны использовать SingleOrDefault
или FirstOrDefault
, соответственно, а не Where
.Where
зарезервирован для сценариев, где вы ожидаете совпадения нескольких вещей, то есть результатом будет список объектов, а не объект.Поскольку вы запрашиваете идентификатор, то совершенно очевидно, что вы ожидаете только одно совпадение.Поэтому:
var memy = db.Memy.SingleOrDefault(s => s.IdMema == id);
Во-вторых, если вам просто нужно прочитать значение Like
, тогда вы можете использовать Select
, но здесь есть две проблемы с этим.Во-первых, Select
может использоваться только для перечислимых элементов, как уже обсуждалось здесь, вам нужен один объект, а не список объектов.По правде говоря, вы можете обойти это несколько запутанным способом:
var amountLike = db.Memy.Select(x => x.Like).SingleOrDefault(x => x.IdMema == id);
Однако это все еще имеет недостатки, потому что вам нужно не только прочитать это значение, но и записать обратно, что затем требуетконтекст объекта, которому он принадлежит.Таким образом, ваш код должен выглядеть следующим образом:
var memy = db.Memy.SingleOrDefault(s => s.IdMema == id);
memy.Like++;
Другими словами, вы извлекаете экземпляр, который хотите изменить, а затем изменяете значение на месте в этом экземпляре.Я также взял на себя смелость использовать оператор приращения здесь, так как это имеет гораздо больший смысл.
Это решает только часть вашей проблемы, так как вам нужно сохранить это значение и в базе данных,конечно.Это также поднимает побочный вопрос о том, как вы получаете свой контекст.Поскольку это контекст EF, он реализует IDisposable
и поэтому должен быть удален, когда вы закончите с ним.Этого можно достичь, просто позвонив по номеру db.Dispose()
, но гораздо лучше использовать вместо него using
:
using (var db = new memyContext())
{
// do stuff with db
}
И пока мы здесь, основываясь на тегах вашего вопроса, вы используетеASP.NET Core, что означает, что даже это не оптимально.ASP.NET Core интенсивно использует DI (внедрение зависимостей) и призывает вас сделать то же самое.Контекст EF обычно регистрируется как служба с областью действия, и поэтому должен быть внедрен там, где это необходимо.У меня нет контекста, где этот код существует, но в целях иллюстрации мы предположим, что он находится в контроллере:
public class MemyController : Controller
{
private readonly memyContext _db;
public MemyController(memyContext db)
{
_db = db;
}
...
}
При этом ASP.NET Core автоматически передаст экземплярваш контекст для конструктора, и вам не нужно беспокоиться о создании контекста или его удалении.Все это обрабатывается для вас.
Наконец, вам нужно проявить настойчивость, но тут все становится сложнее, поскольку вам, скорее всего, придется столкнуться с концепцией параллелизма.Этот код может выполняться одновременно в нескольких разных потоках, каждый из которых запрашивает базу данных в ее текущем состоянии, увеличивает это значение и затем пытается сохранить его обратно.Если вы ничего не делаете, один поток неизбежно перезапишет изменения другого.Например, скажем, мы получаем три «лайка» для этого объекта.Все они запрашивают объект из базы данных, и скажем, что текущее значение счетчика равно 0. Затем каждый из них увеличивает это значение, делая его равным 1, а затем каждый сохраняет результат обратно в базу данных.Конечным результатом является значение, равное 1, но это не правильно: было добавлено три лайка.
Таким образом, вам потребуется реализовать семафор, чтобы по существу использовать эту логику, разрешив только одну подобную операцию.через время для этого конкретного объекта.Здесь это немного выходит за рамки, но в Интернете есть много информации о том, как этого добиться.