NHibernate:仅加载基类对象

2023-12-09

欢迎任何形式的帮助。即使您可以说(根据您的经验)对于如此庞大的层次结构使用 ORM 是疯狂的:)。

背景我的模型层有一个相当庞大的类层次结构,即大约有 200 个类。层次结构的好处/坏处是它们都具有相同的基类。基类和叶类之间的最大距离为 7,层次结构中任何级别的最大类数为 80。 我正在使用 nHibernate 从持久存储中保存/加载数据。

ProblemnHibernate 生成的查询非常高效。例如,如果我想根据基类中某个属性的某些过滤器来选择对象的 id,NHibernate 将尝试连接层次结构/联合中的所有表,具体取决于我选择哪种映射策略,即每个子类一个表或每个类一个表等级制度。

据我所知,nHibernate 在扫描所有相关表之前不会识别哪种类型的对象。但是如果我现在只对基类数据感兴趣怎么办?如何强制 nHibernate 仅加载基类对象。

为了说明我的问题,这是一个简化版本

public class Vehicle
{
    public virtual Guid Identifier { get; set; }
    public virtual int WheelsCount { get; set; }
    public virtual Make Make { get; set; }
    public virtual Model Model { get; set; }
}

public class Bike : Vehicle
{
    public Bike()
    {
        WheelsCount = 2;
    }

    public virtual bool IsDirtBike { get; set; }
}

public class Car : Vehicle
{
    public Car()
    {
        WheelsCount = 4;
    }

    public virtual bool IsFourWheelDrive { get; set; }

    public virtual string Title { get; set; }
    public virtual string Description { get; set; }
}

public class Make
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual IList<Model> Models { get; set; }
}

public class Model
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual Make Make { get; set; }
}

映射如下

public class VehicleMap : ClassMap<Vehicle>
{
    public VehicleMap()
    {
        Id(x => x.Identifier).GeneratedBy.Guid();
        Map(x => x.WheelsCount);

        References(x => x.Make).Column("MakeId");
        References(x => x.Model).Column("ModelId");

        Table("Vehicle");
        Polymorphism.Explicit();
        UseUnionSubclassForInheritanceMapping();
    }
}

public class BikeMap : SubclassMap<Bike>
{
    public BikeMap()
    {
        Map(x => x.IsDirtBike);
        Table("Bike");
        // Abstract();
    }
}

public class CarMap : SubclassMap<Car>
{
    public CarMap()
    {
        Map(x => x.Title);
        Map(x => x.Description);
        Map(x => x.IsFourWheelDrive);
        Table("Car");
       // Abstract();
    }
}

public class MakeMap : ClassMap<Make>
{
    public MakeMap()
    {
        Id(x => x.Id);
        Map(x => x.Name);
        HasMany(x => x.Models)
            .KeyColumn("MakeId");
        Table("Make");
    }
}

public class ModelMap : ClassMap<Model>
{
   public ModelMap()
   {
       Id(x => x.Id);
       Map(x => x.Name);
       References(x => x.Make)
           .Column("MakeId");
       Table("Model");
   }
}

现在,如果运行以下查询来加载四轮车辆,NHibernate 将连接车辆、汽车和自行车表。而我现在只需要存储在 Vehicle 表中的数据

List<Vehicle> vehicles = session.Query < Vehicle > ().Where(v => v.WheelsCount > 2).ToList();

有谁知道我如何强制 nHibernate 仅加载当前需要的数据,即它是否只能返回车辆对象而不是汽车/自行车?只要架构中只有几个表,您就可以忽略 nHibernate 的这些查询,但当您有 200 个表时,这真的很痛苦:(。

附:如果型号有问题,请忽略。这不是真实的模型。如前所述,实际模型要大得多。这个模型就是为了说明这个问题。


NHibernate 必须连接表来决定返回哪种类型。否则多态性就会被破坏。此外,处理诸如抽象基类之类的egde情况也会更加困难。

仅投影您需要的属性,然后就可以开始了

var vehicledatas = session.Query<Vehicle>()
    .Where(v => v.WheelsCount > 2)
    .Select(v => new { v.Id, v.WheelCount, v.Price })
    .ToList();

如果您绝对只需要基类,则针对此用例单独映射它

public class AlternateVehicleMap : VehicleMap
{
    public AlternateVehicleMap()
    {
        EntityName("IAbsolutlyWantOnlyTheBaseClass");
        Readonly();   // to make sure noone messes up
    }
}

List<Vehicle> vehicles = session.CreateCriteria<Vehicle>("IAbsolutlyWantOnlyTheBaseClass").Add(Expression.Gt("WheelsCount", 2).List<Vehicle>();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

NHibernate:仅加载基类对象 的相关文章

随机推荐

  • 使用 php 进行 mysql 查询的进度条

    我正在尝试通过 mysql 查询的迭代来更新进度条 但我无法理解如何更新进度条 以及如何找到我已获取的行数 例如 query SELECT tvshows genres tvshows id show FROM tvshows where
  • Python pandas dataframe“Date”索引xlsx和csv中的不同格式

    我有一个包含多个选项卡的 xlsx 文件 每个选项卡都有一个Date列的格式为MM DD YYYY 将每个选项卡读入 pandas 数据帧 对每个选项卡应用一些操作 然后将数据帧写回两种格式 xlsx 和 csv 在 xlsx 文件中 Da
  • Ajax解析json字符串返回未定义,

    我正在发送一个帖子数据以获取 json 字符串 我的 JSON 字符串 error false success Added Website website id 12 我的阿贾克斯请求 publsher add website on sub
  • Flask 响应 - TypeError:“NoneType”对象不可调用 [重复]

    这个问题在这里已经有答案了 我正在尝试为 Flask REST 服务器创建一个 pytest 在其中一项测试中 我想获得服务器的响应 这是服务器的响应 return make response json dumps myName userN
  • 计算时间差并仅返回小时和分钟(在VB.net中)

    我正在开发一个计算时差的系统 如何比较两个时间 带日期 并获取差异的小时和分钟 示例1 datetime1 1 Apr 2014 01 05 04 AM datetime2 1 Apr 2014 02 05 04 AM 结果将是 datet
  • 如何将 numpy.savetxt 与包含数组的结构化数组一起使用

    假设我有一个结构化数组 如下所示 a np zeros 10 dtype label1 np int32 4 label2 np float 我尝试将其另存为 csv 文件 np savetxt output csv a fmt d d d
  • 使用scale_fill_gradientn将特定颜色分配给条形图中的确定值

    我有一个巨大的数据集 其中包含 20 名患者的一些参数的每分钟记录 通过可视化患者监测记录 IP 参数 我试图构建彩色条形图 所以我用了scale fill gradient r 中的函数 问题是 我想为一个确定的值 例如 IP 20 分配
  • 将新的 AcroForm 字段添加到 PDF

    我使用 iText 将数据填充到 PDF 中现有的 AcroForm 字段中 我现在正在寻找一种将新的 AcroForm 字段添加到 PDF 的解决方案 iText 可以做到这一点吗 如果是这样 我该怎么做 这记录在官方文档 更具体地说 在
  • 在 Yii2 中启用干净的 URL

    如何在 Yii2 中启用干净的 url 我想删除index php 和 来自 url 参数 为此需要在 Yii2 中编辑哪一部分 我在 yii2 中运行成功了 使能够mod rewrite for Apache For basic temp
  • 查找 MySQL 表中 EMPTY 或 NULL 列的计数

    我的 MySQL 表中有大约 30 列 我想计算特定行有多少列字段为空 该表用于存储用户信息 我想找出有多少个人资料字段 例如 姓名 年龄 位置 所有这些字段都存储在单独的列中 为空 尚未由用户填写 我想要细化的列是最后 20 列 因为前
  • VSCode / Virtual Studio Code:无法在 VSCode 终端中加载 Conda 环境

    我正在尝试切换到 VScode 使用内置终端与 Anaconda 交互 并且知道 VScode 支持 Anaconda 因为它随 Anaconda 一起提供 从文档和各种教程 视频中 我看到 conda 虚拟环境被识别 似乎是原生的 但我似
  • 使用内容脚本获取选项卡的 DOM

    我的 popup html 中有一个脚本 我试图通过它获取特定选项卡的 DOM 更具体地说 我试图确定当前页面上特定选项卡中是否存在特定元素 然后在 popup js 中使用此信息 我该怎么做呢 您无法从弹出窗口访问当前页面 DOM 为此
  • 在 Sphinx 中避免来自父级的文档字符串

    我使用 Sphinx 进行自动文档 但我发现它默认将父类文档字符串附加到我的文档字符串的方式很烦人 结果是 对于每个继承自的记录测试类unittest TestCase 我得到了文档字符串 创建一个类的实例 该实例在执行时将使用指定的测试方
  • 可以对故事板发表评论吗?

    因此 我一直在使用 Xcode 7 的新功能在故事板中引用故事板 为了使我的参考资料更加清晰 我想添加一些评论 以准确解释为什么我要拆分故事板 这个功能存在吗 我知道我可以创建一些虚拟视图 但我觉得这很懒而且效率有点低 In you 身份检
  • 在 struts 2 中的同一个操作方法中使用多个结果类型?

    我在操作方法中使用了结果类型流 该方法依赖于 ajax 调用 当焦点移出我的 JSP 上的文本字段时 会激活此 ajax 调用 此 AJAX 调用的功能是 如果用户输入的数据已存在于后端服务器中 则显示错误 基本上 服务器返回一个状态代码
  • 如何使用 C# 监控进程的 IO 活动?

    使用 FileSystemWatcher 我们可以监视特定文件系统的 IO 活动 但是是否有办法知道哪个正在运行的进程导致了该 IO 更具体地说 假设一个正在运行的进程即 abc exe 正在驱动器 D 上创建文件 text txt 我们可
  • 将数字格式化为始终具有符号和小数点分隔符[重复]

    这个问题在这里已经有答案了 我想将任何数字 整数或实数 格式化为字符串表示形式always has a sign 正或负 和小数点分隔符 但没有尾随零 一些样本 3 14 gt 3 14 12 00 gt 12 78 4 gt 78 4 3
  • 这里 Maps Android SDK 调用 PositioningManager start 方法返回 false

    我读了这个问题并尝试了它的答案 但它对我不起作用 我做了一个非常简单的测试应用程序 清单如下
  • laravel 新命令与旧版本

    当我尝试使用以下命令创建新的 Laravel 项目时 laravel new 5 2 blog laravel new blog 5 2 给我以下错误 Crafting application GuzzleHttp Exception Cl
  • NHibernate:仅加载基类对象

    欢迎任何形式的帮助 即使您可以说 根据您的经验 对于如此庞大的层次结构使用 ORM 是疯狂的 背景我的模型层有一个相当庞大的类层次结构 即大约有 200 个类 层次结构的好处 坏处是它们都具有相同的基类 基类和叶类之间的最大距离为 7 层次