web-dev-qa-db-fra.com

Entity Framework crée un nom de table pluriel, mais la vue attend un nom de table unique?

J'utilise le connecteur MySQL .net 6.4.4.0 et le travail Entity Frame 4.1 et j'essaie de créer l'implémentation la plus basique du code en premier.

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

mon modele

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

mon contrôleur à domicile

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

ma vue fortement typée (utilisant l'échafaudage de liste)

@model IEnumerable<Namespace.Models.Vote>

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Value)
        </th>
        <th></th>
    </tr>

    @foreach (var item in Model) {
    <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>

Il crée la table 'votes' dans mySQL avec toutes les bonnes propriétés.

Cependant, il jette sur cette ligne:

@foreach (élément var dans le modèle)

à l'exception:

"La table 'mydb.vote' n'existe pas"

edit: Pour clarifier, je veux en fait la pluralisation du tableau, et il semble bien créer le tableau. J'espère découvrir la raison de la différence singulier/pluriel. Aucun des tutoriels et vidéos de Microsoft/Plural Sight/scott gu ne gère mysql, donc je dois imaginer que le .netconnector pourrait être le coupable. Je voudrais également éviter d'utiliser les attributs [Table ("Votes")]. Fondamentalement, j'espère autant que possible une solution "prête à l'emploi".

edit2 (un code plus pertinent): quand je supprime ceci ... les tables ne parviennent pas à créer toutes ensemble. mais la vue lève une exception à la recherche de "votes" et non de "vote". dans global.asax

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

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

public class myDBInitializer : DropCreateDatabaseAlways<myDB>
{
    protected override void Seed(myDBcontext)
    {
        base.Seed(context);
    }
}
29
nograde

J'ai donc renoncé à essayer de le faire comme je pensais que cela devrait être fait et j'ai supprimé la pluralisation tous ensemble. Je ne sais pas vraiment avec certitude, mais je suppose que le problème est lié à la prise en charge d'EF par le connecteur mysql .net. Voici ce que j'ai fait.

Tout d'abord, il y avait un bogue dans ma méthode ApplicationStart:

//WRONG
//Database.SetInitializer(new DropCreateDatabaseAlways<myDB>());
Database.SetInitializer(new myDBInitializer());

Deuxièmement, j'ai arrêté d'appeler l'implémentation de base OnModelCreating qui n'est pas répertoriée dans le code d'origine car je ne l'ai implémentée que selon la suggestion de jgauffin:

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

Troisièmement, j'ai lu dans certains articles que le connecteur MySQL .net ne permettait pas à EF de CRÉER une base de données, alors j'avais initialement créé la base de données vierge. Cela ne semble plus être le cas avec le connecteur 6.4.4+, et tant que l'utilisateur de votre chaîne de connexion a la possibilité de créer de nouvelles bases de données, cela fonctionne mieux si une n'existe pas initialement.

Une fois, j'ai fait tout ce qui précède, cela a semblé fonctionner. Alors maintenant, je peux au moins aller de l'avant. J'espère que nous pourrons trouver la cause de l'écart pluriel/singulier à l'avenir.

Merci à tous pour leur temps et leurs efforts.

46
nograde

Dans votre classe de contexte myDB, remplacez la méthode suivante

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

pour ne pas pluraliser les noms de table générés.

20
Morten Mertner

Ouvrez la classe DbContext relative aux tables pour lesquelles vous souhaitez conserver un nom de table unique.

Si vous utilisez EF 6, ajoutez une référence à:

using System.Data.Entity.ModelConfiguration.Conventions;

S'il s'agit d'une ancienne version, ajoutez une référence à:

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

Enfin, créez une méthode qui remplace le OnModelCreating et supprimez la convention pour pluraliser les noms de table:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
9
Bartho Bernsmann

Supprimez la coche "Pluralize or singularsize generated object names" lorsque vous créez votre objet entité.

enter image description here

8
Dan

Vous devez remplacer OnModelCreating dans votre DbContext pour spécifier le nom de la table:

modelBuilder.Entity<Vote>().MapSingleType().ToTable("Votes")
3
jgauffin

Si vous utilisez Code First avec EF 6.1 +, remplacez le gestionnaire d'événements OnModelCreating et effectuez les appels suivants:

dmbCloud.Conventions.Remove<PluralizingEntitySetNameConvention>();
dmbCloud.Conventions.Remove<PluralizingTableNameConvention>();
3
Kram