实体框架一对多与每个层次的每个子类创建一个外键列
我有一个 Garage
,其中包含 Cars
和摩托车
。汽车和摩托车是车辆
。这里是:
I have a Garage
which contains Cars
and Motorcycles
. Cars and motorcycles are Vehicles
. Here they are:
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...
}
为什么汽车和摩托车每个都有一个GarageId和Garage属性?如果我把这些属性推到车辆超类,EF会抱怨告诉我导航属性必须位于具体的类中。
Why do Car and Motorcycle each have a GarageId and Garage property? If I push those properties up to the Vehicle superclass, EF complains and tells me navigation properties must reside in concrete classes.
继续,这里是我的DbContext:
Moving on, here's my 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>();
}
}
这是一个简短的程序来玩我的玩具:
And here's a short program to play with my toys:
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();
}
}
}
程序运行并生成以下车辆表:
The program runs, and produces the following Vehicles table:
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
汽车和摩托车都有自己的GarageId和Garage属性,似乎每个子类都在创建自己的外挂车库。如何可以告诉EF(如果可能,通过流畅的api)Car.Garage和Motorcycle.Garage是一样的,应该使用相同的列?
With both Car and Motorcycle having their own GarageId and Garage properties, it seems that each subclass is creating its own foreign key to garage. How do I tell EF (via the fluent api, if possible) that Car.Garage and the Motorcycle.Garage are the same thing, and should use the same column?
这是我想要的车辆表:
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
在汽车和摩托车类的GarageId属性上使用属性[Column(GarageId)]。
Use attribute [Column("GarageId")] on GarageId property on both car and motorcycle class.