使用 EF6 Code First 的 MySQL 现有数据库 - 使用脚手架创建控制器会导致错误

Posted

技术标签:

【中文标题】使用 EF6 Code First 的 MySQL 现有数据库 - 使用脚手架创建控制器会导致错误【英文标题】:MySQL existing DB with EF6 Code First - Controller Creation With Scaffolding Results in Error 【发布时间】:2015-05-08 03:34:25 【问题描述】:

注意:我可以手动创建控制器,获取数据,然后转储到我手动进行强类型化的视图中,但任何搭建脚手架的尝试都会导致此错误。

注意 2:我正在使用 Visual Studio Professional 2013 Update 4

错误是:

运行所选代码生成器时出错:'无法 检索 'WebApplication1.mysqlModels.************* 的元数据。 序列不包含匹配元素'

WebApplication1 是我的测试项目的名称。 MySQLModelsDbContext 文件,其中包含 EF Code First 生成的所有模型,*********** 替换表的名称。

Web.config 自动生成的连接字符串(已替换敏感值):

<add name="stringname" connectionString="server=server;user id=userid;password=password;persistsecurityinfo=True;database=database" providerName="MySql.Data.MySqlClient" />

导致错误的模型类之一:

namespace WebApplication1.MySQLModels

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    using System.Data.Entity.Spatial;

    [Table("database.SomeTable")]
    public partial class SomeTable
    
        public int id  get; set; 

        [StringLength(255)]
        public string CM  get; set; 

        [StringLength(255)]
        public string Job  get; set; 

        [StringLength(255)]
        public string ClientJobNo  get; set; 

        [StringLength(255)]
        public string JobNo  get; set; 

        [StringLength(255)]
        public string Client  get; set; 

        [Column(TypeName = "date")]
        public DateTime? Start  get; set; 

        [Column(TypeName = "date")]
        public DateTime? Finish  get; set; 

        [StringLength(255)]
        public string Frequency  get; set; 

        [StringLength(255)]
        public string PONumber  get; set; 

        [Column(TypeName = "date")]
        public DateTime? AuditCompleted  get; set; 

        [Column(TypeName = "date")]
        public DateTime? Invoiced  get; set; 

        public decimal? InvoiceAmount  get; set; 

        [StringLength(255)]
        public string Query  get; set; 

        [StringLength(255)]
        public string Status  get; set; 

        [StringLength(255)]
        public string Type  get; set; 

        [StringLength(255)]
        public string Area  get; set; 

        [Column(TypeName = "date")]
        public DateTime? PlannedAudit  get; set; 

        [StringLength(255)]
        public string YellowJacketRequired  get; set; 

        [StringLength(255)]
        public string YellowJacketCompleted  get; set; 

        [StringLength(255)]
        public string SuperName  get; set; 

        [StringLength(255)]
        public string SuperPhone  get; set; 

        [StringLength(255)]
        public string ReasonsDateChange  get; set; 

        [Column(TypeName = "text")]
        [StringLength(65535)]
        public string Comments  get; set; 
    

数据库中对应的表定义

CREATE TABLE IF NOT EXISTS `SomeTable` (
`id` int(11) NOT NULL,
  `CM` varchar(255) DEFAULT NULL,
  `Job` varchar(255) DEFAULT NULL,
  `ClientJobNo` varchar(255) DEFAULT NULL,
  `JobNo` varchar(255) DEFAULT NULL,
  `Client` varchar(255) DEFAULT NULL,
  `Start` date DEFAULT NULL,
  `Finish` date DEFAULT NULL,
  `Frequency` varchar(255) DEFAULT NULL,
  `PONumber` varchar(255) DEFAULT NULL,
  `AuditCompleted` date DEFAULT NULL,
  `Invoiced` date DEFAULT NULL,
  `InvoiceAmount` decimal(7,2) DEFAULT NULL,
  `Query` varchar(255) DEFAULT NULL,
  `Status` varchar(255) DEFAULT NULL,
  `Type` varchar(255) DEFAULT NULL,
  `Area` varchar(255) DEFAULT NULL,
  `PlannedAudit` date DEFAULT NULL,
  `YellowJacketRequired` varchar(255) DEFAULT NULL,
  `YellowJacketCompleted` varchar(255) DEFAULT NULL,
  `SuperName` varchar(255) DEFAULT NULL,
  `SuperPhone` varchar(255) DEFAULT NULL,
  `ReasonsDateChange` varchar(255) DEFAULT NULL,
  `Comments` text
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;

ALTER TABLE `SomeTable`
 ADD PRIMARY KEY (`id`);

我对表定义没有太多控制权,因为这是我正在使用的现有数据库。

复制步骤:

    创建一个新的 ASP.NET MVC 5 项目(在我的例子中称为 WebApplication1)

    添加 MySQL DLL:MySql.Data、MySql.Data.Entity.EF6、MySQL.Web。

    将现有的 EntityFramework 标记(在 Web.Config 中)替换为 以下:

    <entityFramework> <defaultConnectionFactory type="MySql.Data.Entity.MySqlConnectionFactory, MySql.Data.Entity.EF6" /> <providers> <provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6" /> </providers> </entityFramework>

    重建项目。

    创建一个文件夹来导入所有模型并创建 DbContext, 在我的情况下,该文件夹是 MySQLModels

    将 ADO.NET 实体数据模型添加到项目中。选择正确的 数据库连接。选择表格并点击完成。

    重建项目。

    右键单击 Controllers 文件夹,然后单击 Add->Controller。在弹出的窗口中选择MVC 5 Controller with views, using Entity Framework并点击添加。

    选择其中一个模型,选择您的数据上下文类,输入 适当的控制器名称,然后单击添加。

    按照此过程,您将看到错误。

到目前为止我所做的尝试:

一般而言,我无法找到与此错误相关的太多信息,但具体与 MySQL 有关。

有一个未回答的问题,没有很多细节,可以在这里找到:https://***.com/questions/24471557/ef6-code-first-existing-mysql-database-scaffolding-errors

    我在这里尝试了这个建议: Unable to Retrieve Metadata 这表明我在连接字符串中更改 providerName 到System.Data.SqlClient,但这会导致同样的错误。

    我从 MySQL 卸载并重新安装了所有内容,但无济于事。

    更新: 为每个表添加单独的 ADO.NET 实体数据模型可解决此问题 错误。这不完全是解决方案,但没有任何其他解决方案 这允许我使用一个 Db 上下文创建脚手架,这可能 工作。

    更新 2:尝试了 Microsoft 的迁移工具: http://www.microsoft.com/en-us/download/details.aspx?id=42657。这 工作,但是,很多数据没有移植过来。再次,这是 最后的努力。仍然不是解决方案。

我会在尝试各种 thingamajigs 时不断更新这个问题以添加更多细节。

【问题讨论】:

【参考方案1】:

这是旧的,但如果有人试图找到修复,这里就是。

指定数据类型的注释是罪魁祸首。 尝试从模型中删除注释。在这种情况下,以下两个

[Column(TypeName = "text")], [Column(TypeName = "date")]

然后构建、清理、构建项目 现在添加控制器(脚手架)就像魅力一样工作。

稍后您可以重新添加相同的内容。

【讨论】:

我从 MySQL 迁移到 SQL Server,因此无法对其进行测试,但我现在会接受您的回答。

以上是关于使用 EF6 Code First 的 MySQL 现有数据库 - 使用脚手架创建控制器会导致错误的主要内容,如果未能解决你的问题,请参考以下文章

亲测Asp.net Mvc5 + EF6 code first 方式连接MySQL总结

使用 EF6(和 Code First 迁移)针对不同的数据库系统

C# Mysql EF6 Code First System.ComponentModel.Win32Exception 文件未找到

在 EF6 Code First 中支持表值函数吗?

使用 EF6 SQL Server CE Code First 创建数据库崩溃

MVC 5 的 EF6 Code First 入门