.NET EF4.1 + MySQL 的类继承

Posted

技术标签:

【中文标题】.NET EF4.1 + MySQL 的类继承【英文标题】:Class Inheritance with .NET EF4.1 + MySQL 【发布时间】:2012-01-02 11:54:45 【问题描述】:

我正在尝试使用 Entity Framework 4.1 和 mysql 作为数据库在 .NET 中实现类继承,并采用代码优先的方法。下面的模型适用于 SQL Server,但在 MySQL 中失败并出现以下错误:

Schema specified is not valid. Errors: 
(11,6) : error 0064: Facet 'MaxLength' must not be specified for type 'mediumtext'.

模型是一个经典的简单例子:

public abstract class Vehicle

    public int Id  get; set; 
    public int Year  get; set; 


public class Car : Vehicle

    public string CarProperty  get; set; 


public class Bike : Vehicle

    public string BikeProperty  get; set; 


public class Db : DbContext

    public DbSet<Vehicle> Vehicles  get; set; 
    public DbSet<Car> Cars  get; set; 
    public DbSet<Bike> Bikes  get; set; 

使用 SQL Server,它只创建一个名为 Vehicles 的表,其列:IdYearModelDiscriminator;没有汽车或自行车的桌子。在 MySQL 中,甚至没有创建数据库(如果我删除“Car”类,它会创建 - 所以这不是权限问题或类似问题)。

任何帮助将不胜感激!谢谢。

更新 1: 我尝试对关系使用 Table-Per-Hierarchy 方法,切换到下面的上下文,但它给了我另一个错误:Can't create table 'aimpa.#sql-da8_2c' (errno: 150)

public class Db : DbContext

    public DbSet<Vehicle> Vehicles  get; set; 

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    
        modelBuilder.Entity<Vehicle>()
            .Map<Car>(o => o.ToTable("Cars"))
            .Map<Bike>(o=>o.ToTable("Bikes"));
    

更新 2: 我已将此作为错误提交给 MySQL 开发团队,因为我不知道我还能做什么。似乎它应该工作,但它没有。永久链接是http://bugs.mysql.com/63920。

更新 3: 我切换到 NHibertnate 3.2,以便对此进行测试。似乎工作得很好。我会更好地了解这个 ORM,但我更愿意继续使用 EF。

更新 4: 在官方 MySQL 论坛中,我received a response 告诉我这个错误的修复正在审查中。应该很快就会修复。

【问题讨论】:

我没有使用继承,但得到完全相同的错误。事实上,我什至找不到设置为“mediumtext”的单个数据库列。所以,到目前为止,这个完全是个谜。 我也没有带有 mediumtext 的列,也没有使用继承并得到相同的错误...我在 6.5.4.0 版本中使用 MySQL-Provider 可能是另一个相关的错误:bugs.mysql.com/bug.php?id=64288 【参考方案1】:

我今天也遇到了同样的问题,不同之处在于我不是依靠 Code First 来为我创建表,而是在进行过程中手动创建它们。

我遵循了here 给出的描述,最终遇到了和你一样的错误,我在我的表上手动创建了一个“鉴别器”字段并将其类型更改为 MEDIUMTEXT,但提供商坚持说我以某种方式提供一个 MaxLength 属性,即使 MEDIUMTEXT 没有像 VARCHAR 这样的 MaxLength,我认为这一定是提供程序的一个错误。

好吧,为了解决这个问题,我使用了 fluent API 来手动告诉鉴别器列名称(我只是保留为“鉴别器”)和 EF 应该从鉴别器列中得到的值,在你的情况下,这将是:

protected override void OnModelCreating(DbModelBuilder modelBuilder)

    modelBuilder.Entity<Vehicle>()
            .Map<Car>(m => m.Requires("Discriminator").HasValue("Car"))
            .Map<Bike>(m => m.Requires("Discriminator").HasValue("Bike"));

我已将鉴别器列的类型更改为 VARCHAR(50),没有明显问题,现在它对我来说效果很好。对我来说,另一种选择是迁移到另一个工作量太大的 ORM,我将等待 MySql 提供程序的下一个版本并测试他们是否已修复此问题,同时我将坚持此解决方案。

【讨论】:

以上是关于.NET EF4.1 + MySQL 的类继承的主要内容,如果未能解决你的问题,请参考以下文章

继承(JAVA)

工厂模式——工厂方法模式

继承log4.net的类

.NET 中具有深度继承的类的内存分配

无法在 ADO .NET 实体模型 edmx 中的类继承中执行覆盖

Java学习(十三)