0

我正在尝试在 EF 4.3 CodeFirst 中为现有的 Oracle 数据库(我无法控制)实现 TPC 继承模型。我有几个子类型,每个子类型都映射到自己的表。不幸的是,一些键列是数据类型number(18,0)而不是integer. EF现在好像很讨厌我。

这是我的基类:

public abstract class Vehicle
{
    public virtual int Id { get; set;}
    public virtual string Color { get; set; }
    //more properties
}

以下是一些示例子类型:

public class Car : Vehicle
{        
    //more properties
}

public class Truck : Vehicle
{
    //more properties
}

public class Motorcycle : Vehicle
{
    //more properties
}

这是我的 DbContet:

public class VehicleDataContext : DbContext
{
    public DbSet<Vehicle> Vehicles { get; set; }
    public DbSet<Car> Cars { get; set; }
    public DbSet<Truck> Trucks { get; set; }
    public DbSet<Motorcycle> Motorcycles { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Vehicle>().HasKey(x => x.Id);

        modelBuilder.Entity<Car>().Map(m => m.MapInheritedProperties());
        modelBuilder.Entity<Car>().Property(x => x.Id).HasColumnType("decimal");

        modelBuilder.Entity<Truck>().Map(m => m.MapInheritedProperties());
        modelBuilder.Entity<Truck>().Property(x => x.Id).HasColumnType("int");

        modelBuilder.Entity<Motorcycle>().Map(m => m.MapInheritedProperties());
        modelBuilder.Entity<Motorcycle>().Property(x => x.Id).HasColumnType("decimal");

        base.OnModelCreating(modelBuilder);
    }
}

所以,我已经知道将MapInheritedProperties基类型和子类型的所有属性映射到一个表。我假设我必须告诉基地,HasKey这样 EF 才不会抱怨我DbSet<Vehicle>没有映射键。我希望能够假设我可以“告诉”每个实体如何映射自己的键的列类型,就像我在上面所做的那样。但我认为这还不够。

这是一个失败的测试:

[TestFixture]
public class when_retrieving_all_vehicles
{
    [Test]
    public void it_should_return_a_list_of_vehicles_regardless_of_type()
    {
        var dc = new VehicleDataContext();
        var vehicles = dc.Vehicles.ToList(); //throws exception here
        Assert.Greater(vehicles.Count, 0);
    }
}

抛出的异常是:

概念侧属性“Id”已映射到类型为“decimal”的存储属性。如果概念侧属性映射到存储模型中的多个属性,请确保存储模型中的所有属性都具有相同的类型。

如上所述,我无法控制数据库及其类型。关键类型混合在一起很愚蠢,但“就是这样”。

我怎样才能解决这个问题?

4

1 回答 1

2

您无法通过映射来实现它。这首先是 EF 代码的限制。您只能将继承结构中的每个属性(包括键)映射一次。因此,您可以在继承树的所有实体中使用整数或小数,但不能混合使用。

顺便提一句。如果您尝试使用int整个decimal继承树,会发生什么?加载或持久化实体是否失败?如果不是,您可以简单地decimal对所有实体使用一个(如果它可以使用整个范围)。

于 2012-06-25T22:30:14.960 回答