Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
554 views
in Technique[技术] by (71.8m points)

entity framework 4.1 - Class Inheritance with .NET EF4.1 + MySQL

I'm trying to implement class inheritance in .NET using Entity Framework 4.1 and MySQL as database, with code-first approach. The model below works with SQL Server, but fails in MySQL with the following error:

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

The model is a classic simple example:

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; }
}

With SQL Server, it creates only a table named Vehicles with columns: Id, Year, Model and Discriminator; no tables for Cars or Bikes. In MySQL, the database is not even created (if I remove the "Car" class, it creates - so it's not a problem of permission or something like that).

Any help would be appreciate! Thank you.

UPDATE 1: I tried using Table-Per-Hierarchy approach to the relationship, switching to the context below, but it gave me another error: 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"));
    }
}

UPDATE 2: I've submitted this as a bug to MySQL development team, because I don't know what more can I do. It seems that it should work, but it doesn't. The permanent link is http://bugs.mysql.com/63920.

UPDATE 3: I switched to NHibertnate 3.2, in order to test this. Seems to work just fine. I'll take a better look at this ORM, but I would prefer still staying with EF.

UPDATE 4: In the official MySQL forum, I received a response telling that the fix for this bug is in review. Should be fixed soon.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I was faced with the same problem today, the difference is that I'm not relying on Code First to create the tables for me, I'm creating them manually as I go.

I have followed the description given here and I ended up on the same error as you, I have manually created a "Discriminator" field on my table and changed its type to MEDIUMTEXT but the provider insisted that I was somehow providing a MaxLength property, even though MEDIUMTEXT has no MaxLength like VARCHAR, I assume this must be a bug on the provider.

Well, to work around this I have used fluent API to manually tell the discriminator column name (which I just kept as "Discriminator") and values that EF should expect from the discriminator column, in your case this would be:

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"));
}

I've changed the type of my discriminator column to VARCHAR(50) with no apparent problem, it's working well for me now. The alternative for me would be to migrate to another ORM which is just too much work, I'll wait for the next versions of the MySql provider and test if they have fixed this, meanwhile I'll stick to this solution.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...