epa*_*alm 10 c# entity-framework one-to-many table-per-hierarchy
我有一个Garage包含Cars和Motorcycles.汽车和摩托车是Vehicles.他们来了:
public class Garage
{
public int Id { get; set; }
public virtual List<Car> Cars { get; set; }
public virtual List<Motorcycle> Motorcycles { get; set; }
public Garage()
{
Cars = new List<Car>();
Motorcycles = new List<Motorcycle>();
}
}
public abstract class Vehicle
{
public int Id { get; set; }
public string Make { get; set; }
public string Model { get; set; }
}
public class Car : Vehicle
{
public int GarageId { get; set; }
public virtual Garage Garage { get; set; }
// some more properties here...
}
public class Motorcycle : Vehicle
{
public int GarageId { get; set; }
public virtual Garage Garage { get; set; }
// some more properties here...
}
Run Code Online (Sandbox Code Playgroud)
为什么Car和Motorcycle都有GarageId和Garage属性?如果我将这些属性推送到Vehicle超类,EF抱怨并告诉我导航属性必须驻留在具体类中.
继续,这是我的DbContext:
public class DataContext : DbContext
{
public DbSet<Garage> Garages { get; set; }
public DbSet<Vehicle> Vehicles { get; set; }
public DbSet<Car> Cars { get; set; }
public DbSet<Motorcycle> Motorcycles { get; set; }
public DataContext()
: base("GarageExample")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个与我的玩具一起玩的简短程序:
class Program
{
static void Main(string[] args)
{
Database.SetInitializer<DataContext>(new DropCreateDatabaseAlways<DataContext>());
using (var db = new DataContext())
{
var car1 = new Car { Make = "Subaru", Model = "Legacy" };
var car2 = new Car { Make = "Porche", Model = "911" };
var bike1 = new Motorcycle { Make = "Suzuki", Model = "GS500" };
var bike2 = new Motorcycle { Make = "Kawasaki", Model = "Ninja" };
var garage = new Garage();
garage.Cars.Add(car1);
garage.Cars.Add(car2);
garage.Motorcycles.Add(bike1);
garage.Motorcycles.Add(bike2);
db.Garages.Add(garage);
db.SaveChanges();
}
}
}
Run Code Online (Sandbox Code Playgroud)
该程序运行,并生成以下车辆表:
Id Make Model GarageId GarageId1 Discriminator
1 Subaru Legacy 1 null Car
2 Porche 911 1 null Car
3 Suzuki GS500 null 1 Motorcycle
4 Kawasaki Ninja null 1 Motorcycle
Run Code Online (Sandbox Code Playgroud)
由于Car和Motorcycle都有自己的GarageId和Garage属性,似乎每个子类都在创建自己的车库外键.我怎么告诉EF(通过流畅的api,如果可能的话)Car.Garage和Motorcycle.Garage是同一个东西,应该使用相同的列?
这当然是我想要的车辆表:
Id Make Model GarageId Discriminator
1 Subaru Legacy 1 Car
2 Porche 911 1 Car
3 Suzuki GS500 1 Motorcycle
4 Kawasaki Ninja 1 Motorcycle
Run Code Online (Sandbox Code Playgroud)
小智 -1
你看过这个了吗?
\n\n\n\n\n映射每个层次结构表 (TPH) 继承
\n\n在 TPH 映射方案中,继承层次结构中的所有类型都映射到单个表。鉴别器列用于识别每行的类型。使用 Code First 创建模型时,TPH 是参与继承层次结构的类型的默认策略。默认情况下,鉴别器列将以名称 \xe2\x80\x9cDiscriminator\xe2\x80\x9d 添加到表中,并且层次结构中每种类型的 CLR 类型名称\n 用于鉴别器值。您可以使用 Fluent API 修改\n 默认行为。
\n
modelBuilder.Entity<Course>() \n.Map<Course>(m => m.Requires("Type").HasValue("Course")) \n.Map<OnsiteCourse>(m => m.Requires("Type").HasValue("OnsiteCourse"));\nRun Code Online (Sandbox Code Playgroud)\n\n直接来自这里开始。
\n