繁体   English   中英

实体框架6 - 代码优先 - FK在继承的类中生成,但关系在基类中定义

[英]Entity Framework 6 - Code first - FK is generated in inherited classes but relation is defined in base class

我想要的是有一个基类和两个单独的继承类列表。 这是我的模特:

public class Instance
{
    public int InstanceId { get; set; }
    public virtual ICollection<User> Users { get; internal set; }
    public virtual ICollection<MasterUser> MasterUsers { get; internal set; }
}  

public abstract class CoreUser
{
    [Key]
    public int UserId { get; set; }
    public int InstanceId { get; set; }
    public virtual Instance Instance { get; set; }
}

[Table("Users")]
public class User : CoreUser
{
    public string UserName { get; set; }
}

[Table("MasterUsers")]
public class MasterUser : CoreUser
{
    public string MasterUserName { get; set; }
}

这是我的DbContext:

public class MyContext : DbContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<MasterUser> MasterUsers { get; set; }
    public DbSet<Instance> Instances { get; set; }
}

这将创建4个具有TPT继承模型的表,这很好。 问题是Users和MasterUsers表将包含Instance的外键(它将被称为Instance_InstanceId),这是多余的,因为此FK是在CoreUser基类中定义的。 这两个FK列甚至没有填充,它们始终为NULL,当您添加User或MasterUser时,将填充CoreUsers InstanceId列。

如果我从Instance类中删除两个引用,如下所示:

public class Instance
{
    public int InstanceId { get; set; }
} 

问题消失但这也使我的应用程序无法使用。 我也可以这样解决我的问题:

public class Instance
{
    public int InstanceId { get; set; }
    public virtual ICollection<CoreUser> Users { get; internal set; }
} 

然后迭代收集过滤掉每种类型的用户,但这种方法将延迟加载所有用户,即使我只想通过MasterUsers迭代。

一种可能的解决方案是使用TPC,但实际上,CoreUser类将包含FK到TPC中不支持的其他一些类(只有层次结构中的顶级类可以包含FK)。 有没有什么办法可以让我在EF中使用Instance类中的两个单独的列表并让它们延迟加载?

编辑

实际上,上面的代码可以正常工作。 如果您引入另一个引用CoreUser的类,它将会中断:

public class UserPolicy
{
    public int PolicyId { get; set; }
    public virtual CoreUser PolicyUser { get; internal set; }
} 

管理来解决这个问题。 我能够使用的解决方案是将CoreUser和Instance之间的关系移动到User和MasterUser,如下所示:

public class Instance
{
    public int InstanceId { get; set; }
    // Still referencing two lists
    public virtual ICollection<User> Users { get; internal set; }
    public virtual ICollection<MasterUser> MasterUsers { get; internal set; }
}  

public abstract class CoreUser
{
    [Key]
    public int UserId { get; set; }
    // No reference to instance. Works if you don't need it from CoreUser
}

[Table("Users")]
public class User : CoreUser
{
    // FK to Instance defined in CoreUser
    public int InstanceId { get; set; }
    public virtual Instance Instance { get; set; }
    public string UserName { get; set; }
}

[Table("MasterUsers")]
public class MasterUser : CoreUser
{
    // FK to Instance defined in MasterUser
    public int InstanceId { get; set; }
    public virtual Instance Instance { get; set; }
    public string MasterUserName { get; set; }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM