Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# EF中不共享主键的多态关联_C#_.net_Entity Framework - Fatal编程技术网

C# EF中不共享主键的多态关联

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

我必须用以下模式支持第三方DB(看起来像RoR风格?)

这里是主表Vehicle,其中VehicleType是一个鉴别器(可能的值是
'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();