1

这是我编写的示例应用程序,它产生的行为与我实际的更复杂的应用程序相同。我显然在某处遗漏了一些配置方面,但我一生都无法弄清楚。出于某种原因,我的 KID 类中的每个集合都在 Sweet 表中接收自己的字段和外键......据我所知,这不是必需的......?如何停止 EF 生成这些?

示例类、配置和生成的迁移代码如下(注意,如果我使用 TPT 而不是 TPH,则不会添加额外的字段,并且 OwnerId 被用作关系字段就好了)

我的课程:

    public class Sweet
    {
        [Key]
        public int SweetId { get; set; }
        public string SweetName { get; set; }

        [ForeignKey("OwnerId")]
        public Kid Owner { get; set; }
        public int OwnerId { get; set; }
    }
    public class Chocolate : Sweet {}
    public class HardBoiled : Sweet {}
    public class Chewy : Sweet {}

    public class Kid
    {
        public int KidId { get; set; }
        public string FirstName { get; set; }
        public virtual ICollection<Chocolate> Chocolates { get; set; }
        public virtual ICollection<HardBoiled> BaggedSweeets { get; set; }
        public virtual ICollection<Chewy> PacketSweets { get; set; }
    }

我的配置(从 OnModelCreating 调用)

public class SweetConfiguration : EntityTypeConfiguration<Sweet>
{
    public SweetConfiguration()
    {
        Map(m => m.ToTable("Sweet"));

        Map<Chocolate>(i => i.Requires("SweetType").HasValue(1));

        Map<Chewy>(i => i.Requires("SweetType").HasValue(2));

        Map<HardBoiled>(f => f.Requires("SweetType").HasValue(3));
    }
}

生成的迁移代码:

    public override void Up()
    {
        CreateTable(
            "dbo.Kid",
            c => new
                {
                    KidId = c.Int(nullable: false, identity: true),
                    FirstName = c.String(),
                })
            .PrimaryKey(t => t.KidId);

        CreateTable(
            "dbo.Sweet",
            c => new
                {
                    SweetId = c.Int(nullable: false, identity: true),
                    SweetName = c.String(),
                    OwnerId = c.Int(nullable: false),
                    Kid_KidId = c.Int(), <--- DON'T NEED THIS
                    Kid_KidId1 = c.Int(), <--- OR THIS
                    Kid_KidId2 = c.Int(), <-- OR THIS!
                    SweetType = c.Int(),
                })
            .PrimaryKey(t => t.SweetId)
            .ForeignKey("dbo.Kid", t => t.Kid_KidId)  <!-- LIKEWISE FOR THESE THREE KEYS
            .ForeignKey("dbo.Kid", t => t.Kid_KidId1)
            .ForeignKey("dbo.Kid", t => t.Kid_KidId2)
            .ForeignKey("dbo.Kid", t => t.OwnerId, cascadeDelete: true)
            .Index(t => t.Kid_KidId)
            .Index(t => t.Kid_KidId1)
            .Index(t => t.Kid_KidId2)
            .Index(t => t.OwnerId);

    }

更新:

由于不支持我当前的模型,我已经像这样更改了我的 Kid 类:

public class Kid
{
    public int KidId { get; set; }
    public string FirstName { get; set; }
    public virtual ICollection<Sweet> Sweets { get; set; }

    [NotMapped]
    public ICollection<HardBoiled> BaggedSweets
    {
        get
        {
            return Sweets.OfType<HardBoiled>().ToList();
        }
    }
    ... and two more read-only NotMapped properties for the other collections...
}
4

1 回答 1

1

您不能在此模型中使用三个集合。EF 期望反向属性和 FK 属性 ( Ownerand OwnerId)直接在集合引用的类中声明Chocolate(即 in和HardBoiledand Chewy),而不是在基类中。为了使其工作并且只有一个外键,您只能定义一个导航集合,该集合Kid引用在其中声明OwnerOwnerId声明的基类:

public class Kid
{
    public int KidId { get; set; }
    public string FirstName { get; set; }
    public virtual ICollection<Sweet> Sweets { get; set; }
}

Sweets.OfType<Chocolate>()(顺便说一句,您可以使用等从该集合中提取特定类型)

TPT 也是如此。有没有可能你的 TPT 测试中没有SweetConfiguration和没有?DbSet<Sweet>这将导致模型根本没有继承(从 EF 的角度来看),因为基类的所有属性都Sweet将添加到三个子表中。

于 2013-10-02T18:58:25.183 回答