【问题标题】:How to prevent Nhibernate from fetching derived class?如何防止 Nhibernate 获取派生类?
【发布时间】:2012-11-29 10:18:14
【问题描述】:

我正在使用 Nhibernate,但在获取具有多个派生类的基类(每个类映射不同的表)时遇到问题。当我查看请求时,Nhibernate 会加入每个派生表,这会对性能产生巨大影响...

这是我的课程的简化图:

public class Animal{
    public virtual int ID { get; set;}
    public virtual string Name { get; set;}
}

public class Dog : Animal{
    //others properties
}

public class Cat: Animal{
    //others properties
}

public class Person{
    public virtual int ID { get; set;}
    public virtual IEnumerable<Animal> Animals { get; set;}
}

一个人有一个动物列表,我只想要他们的名字。这个例子并不完美,而且更复杂(银行程序),但它很好地反映了我的问题。 我知道它可以做不同的等等,但它是一个遗产,所以我别无选择......

提前致谢。

【问题讨论】:

  • 请在您选择名称的地方发布您的查询并提及您的继承映射策略(我假设每个子类都有一个表,但有或没有鉴别器?)。另外,您使用的是哪个版本的 NHibernate?
  • @cremor 每个子类的表不需要鉴别器列。
  • @cremor 我使用的是每个子类的表,但没有鉴别器列,我使用的是 3.3 版
  • @Firo 不需要,但有可能。见这里:nhforge.org/doc/nh/en/…

标签: nhibernate nhibernate-mapping fetch linq-to-nhibernate class-table-inheritance


【解决方案1】:

IMO NHibernate 只会连接包含投影列的表。定义查询但不返回 Person 而是将您需要的属性投影到 dto/anonymous 类中

【讨论】:

  • 这个 Animal 类将在许多其他映射类中被引用(它在应用程序的主表上)所以我认为你的解决方案在我的情况下是不可行的。
  • @Eric 如果您需要完整的 Animal 类,那么 NHibernate 为什么不获取它呢?它无法将 Dogs 作为普通 Animals 获取,因为那是错误的(假设您有检查类型或类似内容的代码)。获取完整对象或仅获取名称字符串,两者之间没有任何内容。
  • 你想达到什么目的?如果您告诉 NH 加载动物,它必须加入其他表才能知道它必须创建哪个子类型。如果您知道仅在从其他实体引用时需要名称,则映射不在此层次结构中的不同动物并从所有其他实体引用它
  • Animal 不是抽象类型,它包含很多信息,这些信息在我的大多数查询中都足够了,因此在我的情况下,Nhibernate 没有理由加载派生类
  • @Eric 看到我的最后评论。运行时类型很重要,因为可能存在多态性、类型检查、强制转换等都会失败。所以 NH 做了唯一正确的事情并加入了其他表
【解决方案2】:

毕竟,我创建了一个由 Dog、Cat 等继承的类 AnimalBase 和一个没有任何子级的 Animal 类(两者都有接口 IAnimal)。

在我 95% 的请求中,我只需要 Animal,我在我的其他对象(如 Person)中引用了这个类。

不完美,但我没有找到更好的...

感谢 Firo 的帮助。

【讨论】:

    猜你喜欢
    • 2014-01-09
    • 2017-05-29
    • 1970-01-01
    • 2020-04-07
    • 1970-01-01
    • 2020-03-13
    • 1970-01-01
    • 2015-11-04
    • 1970-01-01
    相关资源
    最近更新 更多