NHibernate:仅加载基类对象

欢迎任何forms的帮助。 即使您可以说(根据您的经验),使用ORM进行如此庞大的层次结构也是疯狂的:)。

Backgroud我的模型层有一个非常庞大的类层次结构,即大约有200个类。 层次结构的好/坏是它们都具有相同的基类。 基类和叶类之间的最大距离是7,层次结构中任何级别的最大数量类是80.我使用nHibernate来保存/加载来自持久存储的数据。

问题 nHibernate生成的查询非常有效。 例如,如果我想基于对基类中的属性的某些filter来选择对象的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 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 { 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 { public BikeMap() { Map(x => x.IsDirtBike); Table("Bike"); // Abstract(); } } public class CarMap : SubclassMap { public CarMap() { Map(x => x.Title); Map(x => x.Description); Map(x => x.IsFourWheelDrive); Table("Car"); // Abstract(); } } public class MakeMap : ClassMap { public MakeMap() { Id(x => x.Id); Map(x => x.Name); HasMany(x => x.Models) .KeyColumn("MakeId"); Table("Make"); } } public class ModelMap : ClassMap { public ModelMap() { Id(x => x.Id); Map(x => x.Name); References(x => x.Make) .Column("MakeId"); Table("Model"); } } 

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

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

有谁知道我怎么能强制nHibernate只加载当前需要的数据,即它是否只能返回车辆对象而不是汽车/自行车? 在你的模式中只有几个表,你可以通过nHibernate忽略这些查询,但是当你有200个表时它真的很痛:(。

PS如果型号有故障,请忽略它。 这不是真正的模型。 如前所述的实际模型要大得多。 这个模型用于说明问题。

NHibernate必须连接表来决定返回哪种类型。 否则多态性将被打破。 另外,处理egde例如抽象基类等会更加困难。

只投影你需要的属性,你很高兴

 var vehicledatas = session.Query() .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 vehicles = session.CreateCriteria("IAbsolutlyWantOnlyTheBaseClass").Add(Expression.Gt("WheelsCount", 2).List();