我有一个模型层次结构配置如下:
[Table("A")]
abstract class A { }
class B : A { } // treated as abstract
[Table("C")]
class C : B { }
这导致A和B的TPH,以及C的TPT。到目前为止,这似乎工作正常。生成两个数据库表:“A”包含A和B模型记录,“C”仅包含尚未保存在表“A”中的C模型记录列。
对于表A中的TPH安排,有一个生成的“Discriminator”列,EF CF自己创建该列以区分类型A和类型B.此列很好并且是预期的;但是,我想重命名。为了这篇文章,新名称可能是“Type”。
记录如何执行此操作的教程似乎表明了这一点:
modelBuilder.Entity<A>()
.Map<B>(m=>m.Requires("Type").HasValue(typeof(B).Name))
.Map<C>(m=>m.Requires("Type").HasValue(typeof(C).Name));
这似乎不起作用,因为我在数据库生成过程中遇到运行时错误,说A,B和C类型的模型被添加到同一个表中,并且“映射条件可用于区分这些类型映射到的行。“ (无论这意味着什么。)
我也尝试过:
modelBuilder.Entity<A>()
.Map<B>(m=>m.Requires("Type"))
.Map<C>(m=>m.Requires("Type"));
..以及..
modelBuilder.Entity<A>().Map(m=>m.Requires("Type"));
..即使这些尝试编译并且没有产生运行时错误,似乎也没有效果,因为Discriminator列仍然是“Discriminator”。
我试图在A上创建一个名为“Discriminator”的新字符串属性,我随后将其重命名为该属性的列元数据,但这只给了我两个“Discriminator”列:“Discriminator”和“Discriminator1”。
想法?
答案 0 :(得分:1)
不是严格的答案,只是确认方法应该有效......
我刚刚设法重命名我们正在使用的TPH结构中的鉴别器字段。 层次结构具有枚举值以区分类型 A是基类,B是稍微精炼的版本,C,D和E是具体的类。
A类
B级:A
C级:B
D级:B
E级:A
modelBuilder.Entity<A>()
.Map<B>(m => m.Requires("TypeId").HasValue((int)MyType.ClassB))
.Map<C>(m => m.Requires("TypeId").HasValue((int)MyType.ClassC))
.Map<D>(m => m.Requires("TypeId").HasValue((int)MyType.ClassD))
.Map<E>(m => m.Requires("TypeId").HasValue((int)MyType.ClassE));
我必须记住包含每个派生类类型,即使它从未被用作具体类。最初我忘了包括B,因为我认为它不是必需的,并且鉴别器字段会一直出现。
我可以想象如果你试图映射你的C类,即使它在不同的表中,EF也会有点困惑。
您在评论中提到的错误消息听起来像是某些HasValue要求为不同的类类型生成相同的值 - 也许。
编辑:
只需阅读似乎处理相同错误消息的this。
答案 1 :(得分:0)
您无法为C
映射鉴别器,因为它不是您的TPH层次结构的一部分。试试吧:
modelBuilder.Entity<A>()
.Map<B>(m=>m.Requires("Type").HasValue(typeof(B).Name));