3

我有这样的模型层次结构配置:

[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 型。该列很好且符合预期;但是,我想重命名它。为了这篇文章,新名称可能是“类型”。

记录如何执行此操作的教程似乎暗示了这一点:

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"));

..即使这些尝试编译并没有产生运行时错误,似乎也没有任何效果,因为鉴别器列仍然是“鉴别器”。

我尝试在 A 上创建一个名为“Discriminator”的新字符串属性,随后我将重命名该属性的列元数据,但这只是给了我两个“Discriminator”列:“Discriminator”和“Discriminator1”。

想法?

4

2 回答 2

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 要求正在为不同的类类型产生相同的值 - 也许。

编辑:
只需阅读似乎处理相同的错误消息。

于 2011-07-11T12:26:36.973 回答
0

您无法映射鉴别器,C因为它不是 TPH 层次结构的一部分。试试这个:

modelBuilder.Entity<A>()
            .Map<B>(m=>m.Requires("Type").HasValue(typeof(B).Name));
于 2011-07-11T08:57:57.363 回答