繁体   English   中英

具有一对一关系的抽象类实体框架

[英]Abstract Class with 1 to 1 relationship Entity Framework

使用实体框架,我一直在尝试创建这种关系。 基本上我有1个对象具有Result Result对象是抽象的,因为它必须是从Result继承的3个类之一,即ApprovedRejectedModified

在此处输入图片说明

我正在尝试使用实体框架创建表结构。 最初,我打算使用TPCT(每个具体类型的表)结构,所以将没有Result表,但是如果我想引用Result ,我想将链接保留在Action表中,因此现在我只尝试TPT结构。 我发现TPCT更干净,但是最终,如果TPT是实现我想要的唯一途径,那我很好。

我已经为模型结构尝试了以下变化:

public class Action 
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id {get; set;}

    public int Result_Id {get; set;}

    [ForeignKey("Result_Id")]
    public virtual Result Result {get; set;}

    public string Description {get; set;}
}

public abstract class Result
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id {get; set;}

    [Required]
    public int Action_Id {get; set;}

    [ForeignKey("Action_Id")]
    public virtual Action Action {get; set;}

    public string Comment {get; set;}


    public class Approved : Result
    {
        public string Thing {get; set;}
    }

    public class Rejected : Result
    {
        public string Stuff {get; set;}
    }

    public class Modified : Result
    {
        public string Whatever {get; set;}
    }
}

然后,我在上下文文件中尝试了以下两种策略来实现TPT:

modelBuilder.Entity<Approved>().ToTable("Approved");
modelBuilder.Entity<Rejected>().ToTable("Rejected");
modelBuilder.Entity<Modified>().ToTable("Modified");

或对于TCPT:

modelBuilder.Entity<Approved>().Map(m =>
{
    m.MapInheritedProperties();
    m.ToTable("Approved");
});

modelBuilder.Entity<Rejected>().Map(m =>
{
    m.MapInheritedProperties();
    m.ToTable("Rejected");
});

modelBuilder.Entity<Modified>().Map(m =>
{
    m.MapInheritedProperties();
    m.ToTable("Modified");
});

每当我尝试添加新的迁移时,无论尝试什么,都会遇到此错误: Unable to determine the principal end of an association between the types 'Result' and 'Action'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations. Unable to determine the principal end of an association between the types 'Result' and 'Action'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.

有一次我能使它起作用,是我是否从Action类中删除了此引用:

public int Result_Id {get; set;}

[ForeignKey("Result_Id")]
public virtual Result Result {get; set;}

但是我真的很想保留该引用,因此当我进入数据库获取该Action对象时,我可以立即判断是否有关联的Result ,而不必遍历所有3个Result表来查看是否存在是对该Action的引用(这就是为什么我认为我需要TPT的原因...)

任何帮助使这项工作将不胜感激!

经过大量的研究和反复试验,我发现了获得所需结果所需的条件。 它是TPCT DB结构,并且Action对象能够保留对Result的引用。 这是模型类:

public class Action 
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id {get; set;}

    public virtual Result Result {get; set;} //just virtual here, as Action is the dependent and Result is the principal-- i.e. this Result isn't required

    public string Description {get; set;}
}

public abstract class Result
{
    //got rid of the Result_Id, since it's 1:1 the Action_Id can be the Key

    [Required, Key] //added "Key"
    public int Action_Id {get; set;}

    [ForeignKey("Action_Id")]
    public Action Action {get; set;} //removed this virtual, as Action is Required for Result, that makes Result the principal

    public string Comment {get; set;}


    public class Approved : Result
    {
        public string Thing {get; set;}
    }

    public class Rejected : Result
    {
        public string Stuff {get; set;}
    }

    public class Modified : Result
    {
        public string Whatever {get; set;}
    }
}

以下是来自上下文的流畅的API代码:

//this gave me TPCT like I wanted
modelBuilder.Entity<Approved>().Map(m =>
{
    m.MapInheritedProperties();
    m.ToTable("Approved");
});

modelBuilder.Entity<Rejected>().Map(m =>
{
    m.MapInheritedProperties();
    m.ToTable("Rejected");
});

modelBuilder.Entity<Modified>().Map(m =>
{
    m.MapInheritedProperties();
    m.ToTable("Modified");
});

//this defined the principal-dependent relationship I was missing
modelBuilder.Entity<Action>()
    .HasOptional(a => a.Result)
    .WithRequired(a => a.Action)
    .Map(x => x.MapKey("Action_Id"));

然后它起作用了! 希望这个例子可以帮助其他人。

暂无
暂无

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

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