约束我无法更改领域模型,模型由另一个部门交给我,我试图让他们更改模型但失败了.实际模型比示例复杂得多,并且类之间有很多引用,出于性能原因,使用预先加载或向查询添加连接是不可能的.我可以完全控制源代码、hbm 映射和数据库架构,我可以随心所欲地更改它们(只要我不更改模型类之间的关系).我有很多类似示例中的方法,但我不想修改所有方法.谢谢,尼尔 解决方案 关闭动物类的延迟加载最简单.你说它主要是在内存中.<!-- ... --></class>作为一种变体,您还可以使用 no-proxy,请参阅 这篇文章:据我所知,它仅在 AnimalOwner 实际上是代理时才有效.或您可以对动物所有者使用泛型使引用成为具体类.class AnimalOwner{虚拟 TAnimal OwnedAnimal {get;set;}}CatOwner 类:AnimalOwner{}DogOwner 类:AnimalOwner{}或您可以在单独的表中映射DogOwners 和CatOwners,并在映射中定义具体的动物类型.<!-- ... --><property name="OwnedAninal" class="Cat"/></class><class name="DogOwner"><!-- ... --><property name="OwnedAninal" class="Dog"/></class>或你对 NHibernate 有点乱,正如 这个博客.NH实际上能够返回代理背后的真实对象.这里提出了一个更简单的实现: public static T CastEntity(this object entity) where T: class{var proxy = entity as INHibernateProxy;如果(代理!= null){返回 proxy.HibernateLazyInitializer.GetImplementation() 作为 T;}别的{将实体返回为 T;}}可以这样使用:Dog dog = dogOwner.OwnedAnimal.CastEntity();I have a problem with uninitialized proxies in nhibernateThe Domain ModelLet's say I have two parallel class hierarchies: Animal, Dog, Cat and AnimalOwner, DogOwner, CatOwner where Dog and Cat both inherit from Animal and DogOwner and CatOwner both inherit from AnimalOwner. AnimalOwner has a reference of type Animal called OwnedAnimal.Here are the classes in the example:public abstract class Animal{ // some properties}public class Dog : Animal{ // some more properties}public class Cat : Animal{ // some more properties}public class AnimalOwner{ public virtual Animal OwnedAnimal {get;set;} // more properties...}public class DogOwner : AnimalOwner{ // even more properties}public class CatOwner : AnimalOwner{ // even more properties}The classes have proper nhibernate mapping, all properties are persistent and everything that can be lazy loaded is lazy loaded.The application business logic only let you to set a Dog in a DogOwner and a Cat in a CatOwner.The ProblemI have code like this:public void ProcessDogOwner(DogOwner owner){ Dog dog = (Dog)owner.OwnedAnimal; ....}This method can be called by many diffrent methods, in most cases the dog is already in memory and everything is ok, but rarely the dog isn't already in memory - in this case I get an nhibernate "uninitialized proxy" but the cast throws an exception because nhibernate genrates a proxy for Animal and not for Dog.I understand that this is how nhibernate works, but I need to know the type without loading the object - or, more correctly I need the uninitialized proxy to be a proxy of Cat or Dog and not a proxy of Animal.ConstraintsI can't change the domain model, the model is handed to me by another department, I tried to get them to change the model and failed.The actual model is much more complicated then the example and the classes have many references between them, using eager loading or adding joins to the queries is out of the question for performance reasons.I have full control of the source code, the hbm mapping and the database schema and I can change them any way I want (as long as I don't change the relationships between the model classes).I have many methods like the one in the example and I don't want to modify all of them.Thanks,Nir 解决方案 It's easiest to turn off lazy loading for the animal class. You say it's mostly in memory anyway.<class name="Animal" lazy="false"><!-- ... --></class>As a variant of that, you could also use no-proxy, see this post:<property name="OwnedAnimal" lazy="no-proxy"/>As far as I can see, it only works when the AnimalOwner actually is a proxy.ORYou can use generics on the animal owner to make the reference a concrete class.class AnimalOwner<TAnimal>{ virtual TAnimal OwnedAnimal {get;set;}}class CatOwner : AnimalOwner<Cat>{}class DogOwner : AnimalOwner<Dog>{}ORYou can map the DogOwners and CatOwners in separate tables, and define the concrete animal type in the mapping.<class name="CatOwner"> <!-- ... --> <property name="OwnedAninal" class="Cat"/></class><class name="DogOwner"> <!-- ... --> <property name="OwnedAninal" class="Dog"/></class>ORYou mess a little around with NHibernate, as proposed in this blog. NH is actually able to return the real object behind the proxy. Here a bit simpler implementation as proposed there: public static T CastEntity<T>(this object entity) where T: class { var proxy = entity as INHibernateProxy; if (proxy != null) { return proxy.HibernateLazyInitializer.GetImplementation() as T; } else { return entity as T; } }which can be used like this:Dog dog = dogOwner.OwnedAnimal.CastEntity<Dog>(); 这篇关于在 NHibernate 中获取正确类型的代理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-19 18:38