C# EF中不共享主键的多态关联
我必须用以下模式支持第三方DB(看起来像RoR风格?) 这里是主表Vehicle,其中VehicleType是一个鉴别器(可能的值是C# EF中不共享主键的多态关联,c#,.net,entity-framework,C#,.net,Entity Framework,我必须用以下模式支持第三方DB(看起来像RoR风格?) 这里是主表Vehicle,其中VehicleType是一个鉴别器(可能的值是'Car'和'Bike')。因此,如果VehicleType=“Car”则子ID指向Car表中的记录,如果VehicleType=“Bike”则指向Bike表中的记录 和plus表不共享主键值 我想在代码中避免复杂的逻辑,但我不明白我是否可以在这里使用继承(所以Car:Vehicle和Bike:Vehicle),或者至少可以使用导航属性(所以Car.Vehicle
'Car'
和'Bike'
)。因此,如果VehicleType=“Car”
则子ID指向Car表中的记录,如果VehicleType=“Bike”
则指向Bike表中的记录
和plus表不共享主键值
我想在代码中避免复杂的逻辑,但我不明白我是否可以在这里使用继承(所以Car:Vehicle
和Bike:Vehicle
),或者至少可以使用导航属性(所以Car.Vehicle
和Bike.Vehicle
)。所以问题是我能用这个吗?如何实现这一点
表不共享主键值
因此,没有办法将其映射到一个继承模式,而该继承模式应该是。不同的主键值会阻止这种情况
剩下的就是映射相互连接的不同类,这样您至少可以使用导航属性,而不是手动连接不相关的实体。我找到了一种方法,但并不理想。事实上,这很做作。但是看看这对你来说是否是一个可行的解决方案
我使用了这些课程:
public abstract class Vehicle
{
public int VehicleId { get; set; }
public string Name { get; set; }
public VehicleInfo VehicleInfo { get; set; }
}
public class CarVehicle : Vehicle
{ }
public class BikeVehicle : Vehicle
{ }
public abstract class VehicleInfo
{
public int ID { get; set; }
}
public class CarInfo : VehicleInfo
{
public string Model { get; set; }
}
public class BikeInfo : VehicleInfo
{
public bool IsEbike { get; set; }
}
modelBuilder.Entity<Vehicle>().HasRequired(c => c.VehicleInfo)
.WithOptional().Map(m => m.MapKey("SubId"));
我通过以下方式将表Vehicle
拆分为实体CarVehicle
和BikeVehicle
:
最后,连接类:
public abstract class Vehicle
{
public int VehicleId { get; set; }
public string Name { get; set; }
public VehicleInfo VehicleInfo { get; set; }
}
public class CarVehicle : Vehicle
{ }
public class BikeVehicle : Vehicle
{ }
public abstract class VehicleInfo
{
public int ID { get; set; }
}
public class CarInfo : VehicleInfo
{
public string Model { get; set; }
}
public class BikeInfo : VehicleInfo
{
public bool IsEbike { get; set; }
}
modelBuilder.Entity<Vehicle>().HasRequired(c => c.VehicleInfo)
.WithOptional().Map(m => m.MapKey("SubId"));
如果您试图通过SubId
映射这两个导航属性,EF将不接受它
此模型的主要缺点是,您必须始终以VehicleInfo
对象的形式获取“Info”实体。EF将创建正确的子类型,但其编译时类型为VehicleInfo
。同样,如果设置了VehicleInfo
属性,则必须记住提供正确的类型。您可以通过传递属性在某种程度上缓解这种情况
public class CarVehicle : Vehicle
{
[NotMapped]
public CarInfo CarInfo
{
get { return VehicleInfo as CarInfo; }
set { VehicleInfo = value; }
}
}
。。。在自行车中也是如此。但是您不能在LINQ查询中直接使用此属性,因为它没有(也不能)映射
此外,执行的SQL来自一些简单的东西,如
db.Set<CarVehicle>().Include(c => c.VehicleInfo).ToList();
db.Set().Include(c=>c.VehicleInfo.ToList();
。。。因为EF挖掘了所有继承树,所以非常庞大。如果您不能更改DB模式,那么您所能做的就是创建3个独立的类,而不使用任何继承策略和导航属性,如Car.Vehicle
,因为它们仅在FKs的情况下才可能。谢谢@SlavaUtesinov,看起来您是对的。谢谢。是基尼斯!这很有帮助:)
db.Set<CarVehicle>().Include(c => c.VehicleInfo).ToList();