Fluent nhibernate NHibernate要求事件是虚拟的?

Fluent nhibernate NHibernate要求事件是虚拟的?,fluent-nhibernate,nhibernate-mapping,Fluent Nhibernate,Nhibernate Mapping,我试图使用NHibernate映射实体层次结构,几乎所有的NHibernate都有事件。但是,在尝试构建会话工厂时,我会收到类似于以下内容的错误消息: Core.Domain.Entities.Delivery:方法 删除计划的\u应该是虚拟的 交付是我的域模型中的一个实体,其事件名为已安排。由于事件不能被声明为虚拟,我不知道如何在这里继续。为什么NHibernate需要虚拟事件?您的映射看起来如何? 你画了一个事件吗 我以前没有遇到过这个问题,但是,我总是在类映射上指定'lazy=false'

我试图使用NHibernate映射实体层次结构,几乎所有的NHibernate都有事件。但是,在尝试构建会话工厂时,我会收到类似于以下内容的错误消息:

Core.Domain.Entities.Delivery:方法 删除计划的\u应该是虚拟的


交付是我的域模型中的一个实体,其事件名为已安排。由于事件不能被声明为虚拟,我不知道如何在这里继续。为什么NHibernate需要虚拟事件?

您的映射看起来如何? 你画了一个事件吗

我以前没有遇到过这个问题,但是,我总是在类映射上指定'lazy=false'属性,这样我的属性就不必声明为虚拟属性。(因为我不喜欢将财产声明为虚拟财产,如果我的商业模式不需要)


如果使用延迟加载,则必须将公共成员声明为虚拟成员,因为NHibernate将在运行时为您的实体创建代理对象。因此,不要使用延迟加载,或者只是将事件声明为虚拟事件——这并不常见,但也是可能的

NHibernate为所有延迟加载的实体创建代理类,并在引用实体但尚未加载的位置使用它们。访问此代理会触发从数据库加载真实实体。这种方法需要在运行时从实体类继承并重写公共成员,因此此成员是虚拟的


还有另一个解决办法。您可以将
proxy=“ISomeInterface”
添加到类声明中。这样,当Proxy只实现给定的接口时,您就不需要虚拟成员。

在惰性加载的对象上实现INotifyPropertyChanged时,我也遇到了同样的问题。问题是,您实际上要处理两个不同的.NET实例,这样当您在实际实例中触发NPC事件时,您将不会从对代理的任何引用中收到它。使其成为虚拟允许代理“转发”此事件。不幸的是,在VB.NET(2005)中不可能将事件定义为虚拟/可重写的,因此我们不得不引入一个C#项目,其中的基类只实现这些虚拟事件,以避免VB问题。另见

如果还有其他的方法,我很想了解我自己,因为我们的方法使代理的透明度比它们应该的要低一些。另外,在需要初始化惰性加载对象时自动重新连接会话似乎有点困难

问候,,
Theo

域模型是用VB.NET编写的。据我所知,在VB中不能将事件声明为虚拟(可重写)。我理解对虚拟成员的要求,我不明白NHibernate为什么需要虚拟事件。事件的add_*和remove_*方法仅用于添加和删除事件的处理程序。它们不访问状态,因此不需要是虚拟的。我已经检查了NHibernate的源代码,似乎是ProxyTypeValidator。CheckAccessibleMembersAreVirtual(System.Type,IList errors)是发生错误的地方。该方法只检查类的所有方法(GetType除外),并验证它们是否是虚拟的。使用接口作为代理类是否意味着引用持久类的其他实体应根据接口声明引用?如果我有一个Order类实现IOrder,并且我使用IOrder作为代理接口,Customer.Orders是否必须是IList类型?我从未使用过这种方法,但我也会对此进行检查。我甚至认为不可能映射事件。您总是指定lazy=false吗?在我的情况下,延迟加载是绝对必要的。在任何情况下指定要加载的实体都是禁止的。我在类级别指定lazy=false。这样,我就不必在不想创建虚拟属性时创建虚拟属性。缺点是NHibernate在检索对象时不使用动态代理:例如,使用动态代理,在检索对象时,NHibernate将只填充对象的Id。仅当访问对象的一个属性时,才会加载整个对象。但是,这不会影响集合的延迟加载。
<class name="MyClass" table="MyTable" lazy="false">
</class>