Я сталкиваюсь с ошибкой при изменении имен столбцов в приложении Model-View-Controller

#c# #asp.net #asp.net-mvc

#c# #asp.net #asp.net-mvc

Вопрос:

Я использую Visual Studio и следовал инструкциям по созданию базы данных фильмов Model-View-Controller. Ссылка на учебное пособие: https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/start-mvc?view=aspnetcore-5.0amp;tabs=visual-studio

Моя цель: заменить имена столбцов, которые появляются при запуске приложения.

В папке Models находится файл C # с именем Movie.cs. Он содержит класс Movie. Адаптируя программу для своих целей, я внес следующие изменения:

  • Название на имя
  • Дата выпуска на сегодняшний день
  • Жанр электронной почты
  • Цена контракта

Я включаю код из файла Movie.cs ниже:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;

namespace MvcMovie.Models
{
    public class Movie
    {
        public int ID { get; set; }
        public string Name { get; set; }

        [DataType(DataType.Date)]
        public DateTime Date { get; set; }
        public string Email { get; set; }
        public decimal Contract { get; set; }
    }
}
 

После внесения этих изменений я открыл папку Views и внутри нее открыл папку Movies. Папка Movies содержит файлы:

  • create.cshtml
  • удалить.cshtml
  • details.cshtml
  • edit.cshtml
  • index.cshtml

Каждый из этих файлов содержал ссылки на название, дату выпуска, жанр и цену. Поэтому я обновил каждое из них до их нового имени, чтобы оно соответствовало названиям Movie.cs.

Ожидаемые результаты: я ожидал, что приложение отобразит новые имена столбцов (имя, дата, адрес электронной почты, контракт).

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

При обработке запроса произошло необработанное исключение. Исключение SQLiteException: ошибка SQLite 1: «нет такого столбца: m.Contract». Microsoft.Data.Sqlite.Исключение SQLiteException.ThrowExceptionForRC(int rc, sqlite3 db)

На странице ошибок внутреннего сервера указано (предположительно) местоположение (выделено жирным шрифтом ниже) проблемы и немного красного текста, чтобы помочь мне точно определить проблему (КРАСНЫЙ ->):

MvcMovie.Контроллеры.MoviesController.Index() в MoviesController.cs

     _context = context;
}
//End of Constructor
// GET: Movies
public async Task<IActionResult> Index()
{
  RED ->  return View(await _context.Movie.ToListAsync());
}

// GET: Movies/Details/5
public async Task<IActionResult> Details(int? id)
{
    if (id == null)
 

Что я пробовал:
Я дважды проверил, что правильно обновил все имена в файле Movie.cs и в файлах Create, Delete, Details, Edit, Index.
Я также попытался зайти в папку Controllers и обновить файл MoviesController.cs новыми именами (имя, дата, адрес электронной почты, контракт). Ниже я включил содержимое файла MoviesController.cs:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using MvcMovie.Data;
using MvcMovie.Models;

namespace MvcMovie.Controllers
{//Constructor using D.I. to inject database context into the controller
    public class MoviesController: Controller
    {
        private readonly MvcMovieContext _context;

        public MoviesController(MvcMovieContext context)
        {
            _context = context;
        }
        //End of Constructor
        // GET: Movies
        public async Task<IActionResult> Index()
        {
            return View(await _context.Movie.ToListAsync());
        }

        // GET: Movies/Details/5
        public async Task<IActionResult> Details(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var movie = await _context.Movie
                .FirstOrDefaultAsync(m => m.ID == id);
            if (movie == null)
            {
                return NotFound();
            }

            return View(movie);
        }

        // GET: Movies/Create
        public IActionResult Create()
        {
            return View();
        }

        // POST: Movies/Create
        // To protect from overposting attacks, enable the specific properties you want to bind to, for 
        // more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create([Bind("ID,Name,Date,Email,Contract")] Movie movie)
        {
            if (ModelState.IsValid)
            {
                _context.Add(movie);
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            return View(movie);
        }

        // GET: Movies/Edit/5
        public async Task<IActionResult> Edit(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var movie = await _context.Movie.FindAsync(id);
            if (movie == null)
            {
                return NotFound();
            }
            return View(movie);
        }

        // POST: Movies/Edit/5
        // To protect from overposting attacks, enable the specific properties you want to bind to, for 
        // more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Edit(int id, [Bind("ID,Name,Date,Email,Contract")] Movie movie)
        {
            if (id != movie.ID)
            {
                return NotFound();
            }

            if (ModelState.IsValid)
            {
                try
                {
                    _context.Update(movie);
                    await _context.SaveChangesAsync();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!MovieExists(movie.ID))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
                return RedirectToAction(nameof(Index));
            }
            return View(movie);
        }

        // GET: Movies/Delete/5
        public async Task<IActionResult> Delete(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var movie = await _context.Movie
                .FirstOrDefaultAsync(m => m.ID == id);
            if (movie == null)
            {
                return NotFound();
            }

            return View(movie);
        }

        // POST: Movies/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> DeleteConfirmed(int id)
        {
            var movie = await _context.Movie.FindAsync(id);
            _context.Movie.Remove(movie);
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }

        private bool MovieExists(int id)
        {
            return _context.Movie.Any(e => e.ID == id);
        }
    }
}
 

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

Комментарии:

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

2. Чтобы прояснить это, добавьте еще одну миграцию. Не удаляйте старый. Затем выполните обновление базы данных

3. Похоже Movie , класс сопоставлен с таблицей базы данных, а его свойства сопоставлены со столбцами таблицы. Это означает, что имя таблицы / имя класса и имена свойств / имена столбцов должны совпадать. Вы меняете имена свойств, что приводит к генерации SQL-запросов с этими именами столбцов, и эти новые имена не найдены в таблице базы данных. вот почему вы получаете эту ошибку. Вы просто хотите изменить то, что отображается в пользовательском интерфейсе? или вы также хотите изменить имена столбцов в базе данных?

4. @RobWhite Спасибо!

5. @ChetanRanpariya Я был бы не против просто изменить то, что отображается в пользовательском интерфейсе, и оставить имена столбцов прежними, если это будет проще. Не могли бы вы порекомендовать правильный способ сделать это?

Ответ №1:

Когда вы сделаете это, вам придется удалить и заново создать базу данных — в базе данных все еще есть старые имена. Другой способ — использовать миграции code first и добавлять миграции, миграции исправят имена (переименуют их) при их создании — еще одна вещь, которую вы можете попробовать, это добавить атрибут аннотации данных к свойству, например :

    [Display(Name = "Email")]
public string Email { get; set; }