ASP.NET MVC 代码第一个 TPH 不起作用,为每个子 class 创建一个 table,为什么?
ASP.NET MVC code first TPH not working, creates one table per sub class, why?
据我了解,Table Per Hierarchy 是 asp.net mvc 代码中的默认值(?)。然而,当我创建一个抽象基础 class 和两个空子 class 时,如果一个 table 带有鉴别器列,则迁移想要创建两个单独的 table。
public abstract class ShippingBase : Entity
{
public ShippingBase()
{ }
public bool IsDefault { get; set; }
}
public class Shipping : ShippingBase
{
public Shipping():base()
{ }
}
public class FlatRateShipping : ShippingBase
{
public FlatRateShipping():base()
{ }
}
我将两个子 class 添加到数据库上下文中:
public virtual IDbSet<Localization.Shipping> Shippings { get; set; }
public virtual IDbSet<Localization.FlatRateShipping> FlatRateShippings { get; set; }
而且我在 OnModelCreating 中没有做任何事情。
我正在使用 ASP.NET 样板,但据我所知,它不会更改任何会产生此结果的设置。我知道如何强制 TPC,但由于 TPH 是默认设置,我还没有找到任何设置它的方法。 有什么方法可以强制 TPH 吗?还是我的 classes 遗漏了什么?
这是最终的迁移:
public override void Up()
{
CreateTable(
"dbo.FlatRateShippings",
c => new
{
Id = c.Int(nullable: false, identity: true),
IsDefault = c.Boolean(nullable: false),
})
.PrimaryKey(t => t.Id);
CreateTable(
"dbo.Shippings",
c => new
{
Id = c.Int(nullable: false, identity: true),
IsDefault = c.Boolean(nullable: false),
})
.PrimaryKey(t => t.Id);
}
那是因为它们继承自抽象 class。抽象 classes 没有资格被映射到 tables,因为它们永远不能自己实例化。你可以在继承链中有一个抽象 class,但只有从它派生的第一个具体 class 会得到一个 table。例如,如果您使 FlatRateShipping
继承自 Shipping
,那么两者的数据将以 dbo.Shippings
(默认复数形式)结束。
如果 FlatRateShipping
继承自 Shipping
没有意义(因为他们在逻辑上是兄弟姐妹,而不是亲子),那么 Shipping
确实太一个名字的通用。将其重命名为更能描述它实际含义的名称,然后使 Shipping
只是 ShippingBase
的具体实现,两者都可以继承。
如果 none 符合您的喜好,您可以简单地使 ShippingBase
不抽象并获得相同的结果(尽管您的 table 将是 dbo.ShippingBases
默认)。
据我了解,Table Per Hierarchy 是 asp.net mvc 代码中的默认值(?)。然而,当我创建一个抽象基础 class 和两个空子 class 时,如果一个 table 带有鉴别器列,则迁移想要创建两个单独的 table。
public abstract class ShippingBase : Entity
{
public ShippingBase()
{ }
public bool IsDefault { get; set; }
}
public class Shipping : ShippingBase
{
public Shipping():base()
{ }
}
public class FlatRateShipping : ShippingBase
{
public FlatRateShipping():base()
{ }
}
我将两个子 class 添加到数据库上下文中:
public virtual IDbSet<Localization.Shipping> Shippings { get; set; }
public virtual IDbSet<Localization.FlatRateShipping> FlatRateShippings { get; set; }
而且我在 OnModelCreating 中没有做任何事情。
我正在使用 ASP.NET 样板,但据我所知,它不会更改任何会产生此结果的设置。我知道如何强制 TPC,但由于 TPH 是默认设置,我还没有找到任何设置它的方法。 有什么方法可以强制 TPH 吗?还是我的 classes 遗漏了什么?
这是最终的迁移:
public override void Up()
{
CreateTable(
"dbo.FlatRateShippings",
c => new
{
Id = c.Int(nullable: false, identity: true),
IsDefault = c.Boolean(nullable: false),
})
.PrimaryKey(t => t.Id);
CreateTable(
"dbo.Shippings",
c => new
{
Id = c.Int(nullable: false, identity: true),
IsDefault = c.Boolean(nullable: false),
})
.PrimaryKey(t => t.Id);
}
那是因为它们继承自抽象 class。抽象 classes 没有资格被映射到 tables,因为它们永远不能自己实例化。你可以在继承链中有一个抽象 class,但只有从它派生的第一个具体 class 会得到一个 table。例如,如果您使 FlatRateShipping
继承自 Shipping
,那么两者的数据将以 dbo.Shippings
(默认复数形式)结束。
如果 FlatRateShipping
继承自 Shipping
没有意义(因为他们在逻辑上是兄弟姐妹,而不是亲子),那么 Shipping
确实太一个名字的通用。将其重命名为更能描述它实际含义的名称,然后使 Shipping
只是 ShippingBase
的具体实现,两者都可以继承。
如果 none 符合您的喜好,您可以简单地使 ShippingBase
不抽象并获得相同的结果(尽管您的 table 将是 dbo.ShippingBases
默认)。