Дата и время по умолчанию получают значение NULL после обновления с помощью сущности - PullRequest
0 голосов
/ 25 февраля 2020

У меня есть таблица с полем DATETIME DEFAULT.

CREATE TABLE People 
(
Id INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
Name VARCHAR(100) NOT NULL,
...
DtOccurrence DATETIME DEFAULT getDATE(),
);

Использование scaffolding для генерации класса и Entitity для контроллеров + представлений. По умолчанию CRUD работает нормально, но если я пытаюсь обновить регистр, [DtOccurrence] получает NULL в базе данных.

Как это исправить? Заранее спасибо

Создание сохранение ОК

enter image description here

Обновление только [Имя] поле отправляет ноль [DtOccurrence] для базы данных, и мой автоматически сгенерированный класс не имеет этого поля [DtOccurrence]:

enter image description here

UPDATE : CONTROLLER Метод создания

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Create([Bind("Id,Name")] People people)
    {
        if (ModelState.IsValid)
        {
                _context.Add(people);
                await _context.SaveChangesAsync();

                return RedirectToAction("Edit", "Pessoas", new { people.Id });
        }
        return View(people);
    }

CONTROLLER Метод редактирования

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Edit(int id, [Bind("Id,Name,")] People people)
    {
        if (id != people.Id)
        {
            return NotFound();
        }

        if (ModelState.IsValid)
        {
            try
            {
                _context.Update(people);
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!PeopleExists(people.Id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }
            return RedirectToAction(nameof(Index));
        }

        return View(people);
    }

Автоматически сгенерированные леса классов

public partial class Pessoa
{
    public Pessoa()
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
}

1 Ответ

1 голос
/ 25 февраля 2020

Как упомянуто в моем комментарии, в то время как ваш начальный запрос на предоставление данных для представления был дан сущностью из контекста БД, объект (Person), который вы возвращаете в своем методе Update, не такой же и не связан с вашим DbContext. Это десериализованная копия. Вызов Update с ним, когда он не содержит всех полей, приведет к тому, что для полей будет установлено значение #null. Вызов Update с таким отсоединенным объектом от клиента также является вектором атаки для несанкционированных обновлений в вашем домене. (Инструменты отладки / плагины могут перехватывать вызов к серверу и изменять данные сущности любым количеством способов.)

public async Task<IActionResult> Edit(int id, [Bind("Id,Name,")] People people)
{
    if (!ModelState.IsValid)
        return View(people);

    var dataPeople = await _context.People.SingleAsync(x => x.id == people.id);
    dataPeople.name = people.name;
    await _context.SaveChangesAsync(); // dataPeople is a tracked entity and will be saved, not people which is acting as a viewmodel.
    return RedirectToAction(nameof(Index));
}

Использование Update создаст оператор обновления, где все поля в сущности будут перезаписаны , Вы можете решить передать незавершенную сущность в представление или неполную сущность обратно из представления, но EF не имеет представления о том, какие данные отсутствуют, потому что они не были предоставлены / изменены, по сравнению с тем, что было очищено, поэтому он обновляет все , Вместо этого вы должны загрузить объект из DbContext на основе предоставленного идентификатора (что приведет к ошибке, если идентификатор не найден), а затем установить свойства, которые вы хотите изменить в этом отслеживаемом объекте, перед вызовом SaveChanges. Это гарантирует, что результирующий оператор обновления SQL содержит только те столбцы, которые вы хотите изменить.

Как общее правило, я рекомендую использовать классы моделей представления для обмена моделями между сервером и клиентом, чтобы было ясно, какие передаваемые данные вокруг на самом деле есть. Передача сущностей между сервером и представлениями является антишаблоном, который подвержен проблемам с производительностью, сериализации, а также преднамеренному и случайному повреждению данных.

Дополнительные проверки должны включать проверку полноты / законности изменений и, возможно, проверка версии # строки или даты последнего изменения между переданной моделью и данными, загруженными из БД, чтобы убедиться, что они совпадают. Когда пользователь открыл страницу, он, возможно, получил версию # 1 записи. Когда они, наконец, отправят форму, если БД вернет версию # 2, это будет означать, что кто-то еще изменил эту строку за это время. (В противном случае вы перезаписываете изменения)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...