实体框架创建复数表名,但视图需要一个单数表名?

Posted

技术标签:

【中文标题】实体框架创建复数表名,但视图需要一个单数表名?【英文标题】:Entity Framework creates a plural table name, but the view expects a singular table name? 【发布时间】:2011-12-17 00:11:14 【问题描述】:

我正在使用 mysql .net 连接器 6.4.4.0 和 Entity Frame work 4.1 并尝试创建最基本的代码优先实现。

public class myDB: DbContext

    public DbSet<Vote> 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);
    

我的强类型视图(使用 List 脚手架)

@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>

它在 mySQL 中创建具有所有正确属性的表“投票”。

但是,它会抛出这一行:

@foreach(模型中的变量项)

除了:

“表 'mydb.vote' 不存在”

编辑: 澄清一下,我实际上想要表格复数,并且似乎可以正确创建表格。我希望找出单数/复数差异的原因。 microsoft / Plural Sight / scott gu 的教程和视频都没有使用 mysql,所以我不得不想象 .netconnector 可能是罪魁祸首。我还想避免使用 [Table("Votes")] 属性。基本上,我希望尽可能多地提供“开箱即用”的解决方案。

edit2(一些更相关的代码): 当我删除这个...表无法一起创建。 但视图抛出一个异常寻找“投票”而不是“投票”。 在 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);
    

【问题讨论】:

使用Table 属性能解决问题吗?如果您不喜欢该属性,也可以使用 fluent API。你用 SQL Express 试过了吗?可能是 MySQL 连接器有问题 我实际上只是尝试在 Vote 类上方添加 [Table("Votes")] ,但问题仍然存在。不,我没有尝试过使用 SQLExpress,因为我需要让它与 mysql 一起工作 :-) ps。使表属性具有投票值,解决了问题。为什么视图期望错误的表名!!??? :( 我根本不懂 MySQL,所以我只能问你是否 100% 确定 MySQL 中的表被命名为 'votes' 而不是 'vote' @cwyers:如果还不算太晚,我从我们当地的 DBA 那里听说,让表名保持单数是一种很好的 DB 做法。 【参考方案1】:

打开与要保留单数表名的表相关的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<PluralizingTableNameConvention>();

【讨论】:

【参考方案2】:

如果您在 EF 6.1 + 中使用 Code First,请覆盖 OnModelCreating 事件处理程序并进行以下调用:

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

【讨论】:

【参考方案3】:

所以我放弃了尝试按照我认为应该这样做的方式去做,并一起删除了复数形式。我不确定,但我认为问题与 mysql .net 连接器对 EF 的支持有关。这就是我所做的。

首先,我的 ApplicationStart 方法中有一个错误:

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

其次,我停止调用未在原始代码中列出的 OnModelCreating 基础实现,因为我只是按照 jgauffin 的建议实现了它:

protected override void OnModelCreating(DbModelBuilder modelBuilder)

    //DONT DO THIS ANYMORE
    //base.OnModelCreating(modelBuilder);
    //modelBuilder.Entity<Vote>().ToTable("Votes")
    modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

第三,我在一些帖子中读到 MySQL .net 连接器不允许 EF 实际上创建数据库,所以我最初创建了空白数据库。连接器 6.4.4+ 似乎不再是这种情况,只要您的连接字符串的用户能够创建新数据库,如果最初不存在数据库,它会更好地工作。

有一次,我完成了以上所有操作,它似乎奏效了。所以现在我至少可以前进了。希望我们能在未来找出导致复数/单数差异的原因。

感谢大家的时间和精力。

【讨论】:

感谢这对我有帮助。如果有人收到以下错误:Can't create table 'yourdb.#sql-440_4fa8' (errno: 150),这意味着您忘记删除其中一个模型上的TableAttribute(错误 150 与外键相关)。【参考方案4】:

在您的 myDB 上下文类中,覆盖以下方法

protected override void OnModelCreating(ModelBuilder modelBuilder)

    modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    base.OnModelCreating(modelBuilder);

让它不复数生成的表名。

【讨论】:

哦,你实际上想要复数表名。在这种情况下,上述内容可能没有帮助。所描述的行为听起来像是 MySQL EF 提供程序中的错误。 这里是 Morten 对帖子的详细解释。 edspencer.me.uk/2012/03/13/… @MortenMertner 是的,我认为他想要它们的复数形式,但我无法想象为什么有人会这样做。如果他们这样做,他们可以将它们称为复数名称!当您引用一个视图时,它会告诉您 Invalid object name 'dbo.viwReports' 它应该是 dbo.viwReport 并且您想在您的数据上下文中使用一个单一的模型,这是非常令人不安的!!!!【参考方案5】:

您需要在 DbContext 中覆盖 OnModelCreating 以指定表名:

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

【讨论】:

谢谢!投票已经被映射到“投票”表,但我这样做只是为了看看它是否可以连接 EF 神奇的“代码隐藏”中的一些点。但是,寻找 mydb.vote 的异常仍然被抛出。【参考方案6】:

在创建实体对象时删除“生成的对象名称的复数或单数”复选标记。

【讨论】:

嗨,丹,感谢您的回复。这实际上是我的第一个 MVC/EF 项目,我使用代码优先的方法。我不完全确定如何访问您截屏的菜单。你能启发我吗?谢谢! 如果您添加新的实体对象并将其指向现有的数据库架构,则此方法有效。

以上是关于实体框架创建复数表名,但视图需要一个单数表名?的主要内容,如果未能解决你的问题,请参考以下文章

单数还是复数数据库表名? [复制]

创建实体时的表名(包含/正则表达式) - 实体框架 - 表前缀

表不存在 Sequelize

具有复数和单数生成相同实体名称的 Lightspeed 数据库优先表

EF搜索数据自动将表名变复数问题

Entity Framework Core 数据库第一种方法复数表名