Получить значение int из базы данных

#entity-framework #asp.net-core

#entity-framework #asp.net-ядро

Вопрос:

Как я могу получить значение int из базы данных? В таблице 4 столбца Id, Автор, Нравится, не нравится.

Я хочу получить количество неприязни и добавить 1. я пытаюсь

 var db = new memyContext();
var amountLike = db.Memy.Where(s => s.IdMema == id).select(like);
memy.like=amountLike 1;
 

Я знаю, что это плохой способ.
Пожалуйста, помогите

Ответ №1:

Я не совсем уверен, в чем заключается ваш вопрос, но есть несколько вещей, которые могут помочь.

Во-первых, если вы извлекаете данные с помощью чего-то, что разумно имеет только одно совпадение, или в сценарии, когда вам нужна только одна вещь, тогда вы должны использовать 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  ;
 

Другими словами, вы извлекаете экземпляр, который хотите изменить, а затем изменяете значение на месте в этом экземпляре. Я также взял на себя смелость использовать здесь оператор increment, поскольку таким образом это имеет гораздо больше смысла.

Это, конечно, решает только часть вашей проблемы, поскольку вам также необходимо сохранить это значение обратно в базу данных. Это также поднимает побочный вопрос о том, как вы получаете свой контекст. Поскольку это контекст EF, он реализует IDisposable и, следовательно, должен быть удален, когда вы закончите с ним. Это может быть достигнуто простым вызовом db.Dispose() , но гораздо лучше использовать using вместо этого:

 using (var db = new memyContext())
{
    // do stuff with db
}
 

И пока мы здесь, основываясь на тегах вашего вопроса, вы используете ASP.NET Ядро, а это значит, что даже это неоптимально. ASP.NET Core активно использует DI (внедрение зависимостей) и призывает вас делать то же самое. Контекст EF обычно регистрируется как служба с ограниченной областью действия и поэтому должен вводиться там, где это необходимо. У меня нет контекста, в котором существует этот код, но для иллюстрации предположим, что он находится в контроллере:

 public class MemyController : Controller
{
    private readonly memyContext _db;

    public MemyController(memyContext db)
    {
        _db = db;
    }

    ...
}
 

При этом, ASP.NET Ядро автоматически передаст экземпляр вашего контекста конструктору, и вам не нужно беспокоиться о создании контекста или его удалении. Все это обрабатывается за вас.

Наконец, вам нужно выполнить фактическое сохранение, но именно здесь все становится сложнее, поскольку теперь вам, скорее всего, придется иметь дело с концепцией параллелизма. Этот код может выполняться одновременно в нескольких разных потоках, каждый из которых запрашивает базу данных в ее текущем состоянии, увеличивает это значение, а затем пытается сохранить его обратно. Если вы ничего не сделаете, один поток неизбежно перезапишет изменения другого. Например, допустим, мы получаем три одновременных «лайка» для этого объекта. Все они запрашивают объект из базы данных, и допустим, что текущее значение like равно 0. Затем каждый из них увеличивает это значение, делая его равным 1, а затем каждый из них сохраняет результат обратно в базу данных. Конечным результатом будет значение 1, но это неверно: только что добавлено три лайка.

Таким образом, вам нужно будет реализовать семафор, чтобы по существу управлять этой логикой, позволяя одновременно выполнять только одну операцию like для этого конкретного объекта. Здесь это немного выходит за рамки, но в Интернете есть много информации о том, как этого добиться.