Entity Framework створює множинне ім'я таблиці, але вигляд очікує однинної назви таблиці?

Я використовую MySQL .net з'єднувач 6.4.4.0 і Entity Frame роботу 4.1 і намагаюся створити самі основні перші реалізації коду.

public class myDB: DbContext
{
    public DbSet Votes { get; set; }
}

моя модель

public class Vote
{
    public Guid Id { get; set; }
    public int Value { get; set; }
}

мій домашній контролер

public class HomeController : Controller
{
    myDB_db = new myDB();
    public ActionResult Index()
    {
        var model = _db.Votes;
        return View(model);
    }
}

мій сильно набраний вигляд (за допомогою спискової ліси)

@model IEnumerable

@{
    ViewBag.Title = "Index";
}

Index


@Html.ActionLink("Create New", "Create") <table> <tr> <th> @Html.DisplayNameFor(model => model.Value) </th> <th></th> </tr> @foreach (елемент var у моделі) { <tr> <td> @Html.DisplayFor(modelItem => item.Value) </td> <td> @Html.ActionLink("Edit", "Edit", new { id=item.Id }) | @Html.ActionLink("Details", "Details", new { id=item.Id }) | @Html.ActionLink("Delete", "Delete", new { id=item.Id }) </td> </tr> } </table>

Він створює таблицю 'votes' у mySQL з усіма правильними властивостями.

Однак він кидає в цю лінію:

@foreach (елемент var у моделі)

за винятком:

"Таблиця" mydb.vote "не існує"

редагувати: Щоб уточнити, я насправді хочу плюралізувати стіл, і, здається, правильно створити таблицю. Я сподіваюся виявити причину неоднозначного/множинного розбіжностей. Жоден з підручників та відео з Microsoft/Plural Sight/scott gu не використовує mysql, тому я повинен уявити, що .netconnector може бути винуватцем. Я також хотів би уникнути використання атрибутів [Таблиця ("Голосів")]. В основному я сподіваюсь на те, щоб якомога більше вирішити рішення "з коробки".

edit2 (ще якийсь релевантний код): коли я видалити це ... таблиці не можуть створити все разом. але вигляд видає виняток, який шукає "голосів", а не "голосує". всередині global.asax

protected void Application_Start()
{
     Database.SetInitializer(new DropCreateDatabaseAlways());

     AreaRegistration.RegisterAllAreas();
     RegisterGlobalFilters(GlobalFilters.Filters);
     RegisterRoutes(RouteTable.Routes);
}

public class myDBInitializer : DropCreateDatabaseAlways
{
    protected override void Seed(myDBcontext)
    {
        base.Seed(context);
    }
}
28
@cwyers: якщо не пізно, то я чув від нашого місцевого DBA і прочитав, що це хороша практика БД, щоб назви табличних назв були сингулярними.
додано Автор Merlyn Morgan-Graham, джерело
Чи використовує атрибут Table вирішити проблему? Ви також можете використовувати простий API, якщо вам не подобається атрибут. Ви пробували це з SQL Express? Може бути, проблема з роз'ємом MySQL
додано Автор flipchart, джерело
Я взагалі не знаю MySQL, тому я можу лише запитати, якщо ви 100% впевнені, що таблиця в MySQL називається "голосами", а не "голосує"
додано Автор flipchart, джерело
Я насправді просто намагався додати [Таблиця ("Голоси")] над класом голосування, і проблема не зникає. і ні, я не намагався використовувати SQLExpress, тому що мені потрібно, щоб він працював з MySQL :-)
додано Автор nograde, джерело
пс в результаті чого атрибут таблиці має значення "Голосувати", виправляє проблему. Чому думка очікує неправильне ім'я таблиці !! ?? :(
додано Автор nograde, джерело
Так, просто увійшов до сервера і перевірив дБ. напевно назвали "голоси".
додано Автор nograde, джерело

6 Відповіді

Таким чином, я відмовився від спроби зробити це так, як я відчував, що це повинно бути зроблено, і видалити плюралізацію всі разом. Я насправді не знаю, але я припускаю, що ця проблема пов'язана з підтримкою EF для connector .net. Ось що я зробив.

По-перше, у моєму методі ApplicationStart виникла помилка:

//WRONG
//Database.SetInitializer(new DropCreateDatabaseAlways());
Database.SetInitializer(new myDBInitializer());

По-друге, я зупинив виклик базової реалізації OnModelCreating, який не вказаний у вихідному коді, оскільки я виконував його лише за пропозицією jgauffin:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    //DONT DO THIS ANYMORE
    //base.OnModelCreating(modelBuilder);
    //modelBuilder.Entity().ToTable("Votes")
    modelBuilder.Conventions.Remove();
}

По-третє, я читаю в деяких публікаціях, що з'єднання MySQL .net не дозволяє EF насправді створювати базу даних, тому спочатку я створив порожню DB. Здається, це більше не стосується з'єднання 6.4.4+, і якщо користувач вашого рядка з'єднання має можливість створювати нові бази даних, він працює краще, якщо він спочатку не існує.

Одного разу я зробив все вище, здавалося, працював. Тож тепер я можу хоча б рухатися вперед. Сподіваємось, ми можемо з'ясувати причину множинного/сингулярного невідповідності в майбутньому.

Спасибі всім за свій час і зусилля.

42
додано
Спасибі це допомогло мені. У випадку, якщо хтось отримає таку помилку: Неможливо створити таблицю 'yourdb. # Sql-440_4fa8' (errno: 150) , це означає, що ви забули видалити TableAttribute одна з ваших моделей (помилка 150 пов'язана із зовнішнім ключем).
додано Автор Marthijn, джерело

У вашому контекстному класі myDB перевизначте наступний метод

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Conventions.Remove();
    base.OnModelCreating(modelBuilder);
}

щоб він не плюралізував створені імена таблиць.

18
додано
О, ви дійсно хочете імена множинних таблиць. Наведене вище не може допомогти у цьому випадку. Описана поведінка звучить як помилка у провайдера MySQL EF.
додано Автор Morten Mertner, джерело
Ось довше пояснення посту Мортен. edspencer.me.uk/2012/03/13/& hellip;
додано Автор Sameer, джерело
Я думаю, ти правий Мортен.
додано Автор nograde, джерело

Зніміть прапорець "Збільшити чи збільшити кількість імен згенерованих об'єктів" під час створення об'єкта об'єкта.

enter image description here

8
додано
Ви не можете з кодом спочатку.
додано Автор jgauffin, джерело
Цей метод працює, якщо ви додаєте новий об'єкт об'єкта і вкажете його в існуючу схему бази даних.
додано Автор Dan, джерело
Гей Дан, дякую за відповідь. це буквально мій перший проект MVC/EF, і я використовую кодовий підхід. Я не зовсім впевнений, як отримати доступ до меню, на якому ви створили скріншот. Ви можете просвітити мене? Дякую!
додано Автор nograde, джерело

Відкрийте клас DbContext , пов'язаний з таблицями, в яких ви хочете зберегти ім'я унікальної таблиці.

Якщо ви використовуєте EF 6, додайте посилання на:

using System.Data.Entity.ModelConfiguration.Conventions;

Якщо це стара версія, додайте посилання на:

using System.Data.Entity.ModelConfiguration.Conventions.Edm.Db;

Нарешті, створіть метод, який замінює OnModelCreating та вилучіть конвенцію для множини імен таблиць:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Conventions.Remove();
}
7
додано

Вам потрібно перевизначити OnModelCreating у вашому DbContext, щоб вказати назву таблиці:

modelBuilder.Entity().MapSingleType().ToTable("Votes")
3
додано
Чи називається лінія? встановіть точку зупинки
додано Автор jgauffin, джерело
Дякую! Голосування вже відображається у таблиці «Голоси», але я наводив це лише на те, щоб побачити, чи може він підключити деякі точки до чарівного коду «за кодом» EF. Проте виключення, що шукає mydb.vote, все ще викидається.
додано Автор nograde, джерело
це називається.
додано Автор nograde, джерело

Якщо ви використовуєте Code First з EF 6.1 +, перейміть обробник подій OnModelCreating та виконайте наступні дзвінки:

dmbCloud.Conventions.Remove();
dmbCloud.Conventions.Remove();
2
додано
var chat = new Chat();
var chat = new Chat();
642 учасників

Обсуждение вопросов по C# / .NET / .NET Core / .NET Standard / Azure Сообщества-организаторы: — @itkpi — @dncuug