实体框架创建复数表名,但视图需要一个单数表名?
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 项目,我使用代码优先的方法。我不完全确定如何访问您截屏的菜单。你能启发我吗?谢谢! 如果您添加新的实体对象并将其指向现有的数据库架构,则此方法有效。以上是关于实体框架创建复数表名,但视图需要一个单数表名?的主要内容,如果未能解决你的问题,请参考以下文章
创建实体时的表名(包含/正则表达式) - 实体框架 - 表前缀