获得正确类型的代理NHibernate的 [英] Getting proxies of the correct type in NHibernate

查看:109
本文介绍了获得正确类型的代理NHibernate的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有在NHibernate的

I have a problem with uninitialized proxies in nhibernate

的域模型

让我们说我有两个平行的类层次:动物,狗,猫和AnimalOwner,DogOwner,CatOwner其中,狗和猫都来自动物和DogOwner和CatOwner从AnimalOwner既继承继承。 。AnimalOwner有称为OwnedAnimal型动物的参考

Let'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.

下面是在实施例中的类

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
}



类有适当的NHibernate的映射,所有属性是持久的,一切可以偷懒装懒加载。

The classes have proper nhibernate mapping, all properties are persistent and everything that can be lazy loaded is lazy loaded.

应用程序的业务逻辑只让你在一个DogOwner并在CatOwner猫设置了狗。

The application business logic only let you to set a Dog in a DogOwner and a Cat in a CatOwner.

问题

我有这样的代码:

public void ProcessDogOwner(DogOwner owner)
{
   Dog dog = (Dog)owner.OwnedAnimal;
   ....
}

这方法可以通过许多不同势称为方法,在大多数情况下,狗已经在内存中,一切都很好,但很少狗是不是已经在内存中 - 在这种情况下,我得到一个NHibernate的未初始化的代理,但剧组抛出,因为NHibernate的genrates的代理例外,动物,而不是狗

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.

我明白这是如何工作的NHibernate的,但我需要知道的类型,而无需加载对象 - 或者,更确切地说,我需要的初始化代理是猫或狗,而不是动物代理的代理。

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.

限制


  • 我不能改变域模型,该模型是交给我的另一个部门,我试图让他们改变模型和失败。

  • 实际的模型要复杂得多,然后这个例子和类之间有许多参考,使用预先加载或添加连接来查询是出于性能方面的原因的问题。

  • 我的源代码中,HBM映射和数据库架构的完全控制,我可以改变他们的任何方式我想(只要我不改变模型类之间的关系)。

  • 我有很多方法,比如一个在这个例子,我不希望修改他们。

  • I 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>



作为其中的一个变种,你也可以使用无代理,见这个帖子

<property name="OwnedAnimal" lazy="no-proxy"/>



据我所看到的,它只能在 AnimalOwner 实际上是一个代理服务器。

As far as I can see, it only works when the AnimalOwner actually is a proxy.

您可以。使用对动物所有者仿制药,使基准的具体类

You 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>
{
}

您可以映射到单独的表的 DogOwners CatOwners ,和。定义映射的具体类型的动物

You 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>

您混乱与NHibernate一点左右,如这个博客提出。 NH实际上是能够返回代理背后的真正对象。拟议这儿有一点简单的实现:

You 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.CastEntit<Dog>();

这篇关于获得正确类型的代理NHibernate的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆