流畅的 NHibernate 映射没有虚拟属性的类

发布于 2024-12-17 12:24:59 字数 3966 浏览 0 评论 0原文

我正在使用 nhibernate 构建自己的会员提供程序。将 MembershipUser 类硬塞到 nhibernate 映射中是一件非常困难的事情,我认为主要是因为基本属性和方法并不都是虚拟的。我的用户类定义为:

public class nhMembershipUser : MembershipUser
{
    public new virtual Guid ProviderUserKey { get; set; }
    public new virtual DateTime LastPasswordChangedDate { get; set; }
    public virtual bool IsEnabled { get; set; }
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
    public virtual string Application { get; set; }
    public new virtual string UserName { get; set; }
    public new virtual bool IsOnline
    {
        get
        {
            var UnitOfWork = new nhUnitOfWork();
            return UnitOfWork.UserIsOnline(this);
        }
    }
    public new virtual bool IsLockedOut { get; set; }
    public virtual IList<nhRole> Roles { get; set; }
    public new virtual bool ChangePassword(string oldPassword, string newPassword)
    {
        throw new NotSupportedException();
    }
    public new virtual bool ChangePasswordQuestionAndAnswer(string password, string newPasswordQuestion, string newPasswordAnswer)
    {
        throw new NotSupportedException();
    }
    public new virtual string ResetPassword()
    {
        throw new NotSupportedException();
    }
    public new virtual string ResetPassword(string passwordAnswer)
    {
        throw new NotSupportedException();
    }
    public new virtual string GetPassword()
    {
        throw new NotSupportedException();
    }
    public new virtual string GetPassword(string passwordAnswer)
    {
        throw new NotSupportedException();
    }
}

当我尝试创建映射时,我得到以下信息:

FluentNHibernate.Cfg.FluentConfigurationException: An invalid or incomplete conf
iguration was used while creating a SessionFactory. Check PotentialReasons colle
ction, and InnerException for more detail.

  * Database was not configured through Database method.
 ---> NHibernate.InvalidProxyTypeException: The following types may not be used
as proxies:
nhApplicationServicesProvider.Entities.nhMembershipUser: method Update should be
 'public/protected virtual' or 'protected internal virtual'
nhApplicationServicesProvider.Entities.nhMembershipUser: method GetPassword shou
ld be 'public/protected virtual' or 'protected internal virtual'
nhApplicationServicesProvider.Entities.nhMembershipUser: method ChangePassword s
hould be 'public/protected virtual' or 'protected internal virtual'
nhApplicationServicesProvider.Entities.nhMembershipUser: method ResetPassword sh
ould be 'public/protected virtual' or 'protected internal virtual'
nhApplicationServicesProvider.Entities.nhRole: method set_RoleId should be 'publ
ic/protected virtual' or 'protected internal virtual'
nhApplicationServicesProvider.Entities.nhRole: method set_Name should be 'public
/protected virtual' or 'protected internal virtual'
   at NHibernate.Cfg.Configuration.ValidateEntities()
   at NHibernate.Cfg.Configuration.Validate()
   at NHibernate.Cfg.Configuration.BuildSessionFactory()
   at FluentNHibernate.Cfg.FluentConfiguration.BuildSessionFactory() in d:\Build
s\FluentNH-v1.x-nh3\src\FluentNHibernate\Cfg\FluentConfiguration.cs:line 227
   --- End of inner exception stack trace ---
   at FluentNHibernate.Cfg.FluentConfiguration.BuildSessionFactory() in d:\Build
s\FluentNH-v1.x-nh3\src\FluentNHibernate\Cfg\FluentConfiguration.cs:line 232
   at nhApplicationServicesProvider.nhSessionFactory.CreateDatabaseSchema() in C
:\Users\JHolovacs\Documents\Projects\nhApplicationServicesProvider\nhApplication
ServicesProvider\nhSessionFactory.cs:line 63
   at nhApplicationServicesProvider.Program.Main() in C:\Users\JHolovacs\Documen
ts\Projects\nhApplicationServicesProvider\nhApplicationServicesProvider\Program.
cs:line 13

  * Database was not configured through Database method.

它特别提到了 GetPassword()、ChangePassword() 和 ResetPassword(),据我所知,它们正确覆盖具有虚方法的基类。

为什么我会收到这些错误,如何解决这个问题?

I'm building my own membership provider using nhibernate. The MembershipUser class is a surprisingly difficult thing to shoehorn into an nhibernate mapping, primarily I think because the base properties and methods are not all virtual. My user class is defined as:

public class nhMembershipUser : MembershipUser
{
    public new virtual Guid ProviderUserKey { get; set; }
    public new virtual DateTime LastPasswordChangedDate { get; set; }
    public virtual bool IsEnabled { get; set; }
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
    public virtual string Application { get; set; }
    public new virtual string UserName { get; set; }
    public new virtual bool IsOnline
    {
        get
        {
            var UnitOfWork = new nhUnitOfWork();
            return UnitOfWork.UserIsOnline(this);
        }
    }
    public new virtual bool IsLockedOut { get; set; }
    public virtual IList<nhRole> Roles { get; set; }
    public new virtual bool ChangePassword(string oldPassword, string newPassword)
    {
        throw new NotSupportedException();
    }
    public new virtual bool ChangePasswordQuestionAndAnswer(string password, string newPasswordQuestion, string newPasswordAnswer)
    {
        throw new NotSupportedException();
    }
    public new virtual string ResetPassword()
    {
        throw new NotSupportedException();
    }
    public new virtual string ResetPassword(string passwordAnswer)
    {
        throw new NotSupportedException();
    }
    public new virtual string GetPassword()
    {
        throw new NotSupportedException();
    }
    public new virtual string GetPassword(string passwordAnswer)
    {
        throw new NotSupportedException();
    }
}

When I'm trying to create my mappings, I'm getting this:

FluentNHibernate.Cfg.FluentConfigurationException: An invalid or incomplete conf
iguration was used while creating a SessionFactory. Check PotentialReasons colle
ction, and InnerException for more detail.

  * Database was not configured through Database method.
 ---> NHibernate.InvalidProxyTypeException: The following types may not be used
as proxies:
nhApplicationServicesProvider.Entities.nhMembershipUser: method Update should be
 'public/protected virtual' or 'protected internal virtual'
nhApplicationServicesProvider.Entities.nhMembershipUser: method GetPassword shou
ld be 'public/protected virtual' or 'protected internal virtual'
nhApplicationServicesProvider.Entities.nhMembershipUser: method ChangePassword s
hould be 'public/protected virtual' or 'protected internal virtual'
nhApplicationServicesProvider.Entities.nhMembershipUser: method ResetPassword sh
ould be 'public/protected virtual' or 'protected internal virtual'
nhApplicationServicesProvider.Entities.nhRole: method set_RoleId should be 'publ
ic/protected virtual' or 'protected internal virtual'
nhApplicationServicesProvider.Entities.nhRole: method set_Name should be 'public
/protected virtual' or 'protected internal virtual'
   at NHibernate.Cfg.Configuration.ValidateEntities()
   at NHibernate.Cfg.Configuration.Validate()
   at NHibernate.Cfg.Configuration.BuildSessionFactory()
   at FluentNHibernate.Cfg.FluentConfiguration.BuildSessionFactory() in d:\Build
s\FluentNH-v1.x-nh3\src\FluentNHibernate\Cfg\FluentConfiguration.cs:line 227
   --- End of inner exception stack trace ---
   at FluentNHibernate.Cfg.FluentConfiguration.BuildSessionFactory() in d:\Build
s\FluentNH-v1.x-nh3\src\FluentNHibernate\Cfg\FluentConfiguration.cs:line 232
   at nhApplicationServicesProvider.nhSessionFactory.CreateDatabaseSchema() in C
:\Users\JHolovacs\Documents\Projects\nhApplicationServicesProvider\nhApplication
ServicesProvider\nhSessionFactory.cs:line 63
   at nhApplicationServicesProvider.Program.Main() in C:\Users\JHolovacs\Documen
ts\Projects\nhApplicationServicesProvider\nhApplicationServicesProvider\Program.
cs:line 13

  * Database was not configured through Database method.

It specifically mentions GetPassword(), ChangePassword(), and ResetPassword() which are, as far as I can tell, properly overwriting the base class with virtual methods.

Why am I getting these errors, and how can I get around this issue?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

东京女 2024-12-24 12:24:59

它特别提到了 GetPassword()、ChangePassword() 和 ResetPassword(),据我所知,它们是用虚拟方法正确覆盖基类的。

不,您没有覆盖这些方法,您只是隐藏了它们。

NHibernate 要求所有非私有属性和方法都是虚拟的,否则它没有机会拦截代理上的调用。

如果您不需要延迟加载该类,只需使用 lazy="false" 映射您的实体,您将不再需要虚拟成员。如果需要延迟加载,可以使用 proxy="ProxyInterface" 代理接口。

It specifically mentions GetPassword(), ChangePassword(), and ResetPassword() which are, as far as I can tell, properly overwriting the base class with virtual methods.

No, you didn't overwrite these methods, you've only hidden them.

NHibernate requires all non-private properties and methods to be virtual, otherwise it has no chance to intercept the calls on a proxy.

If you don't need that class to be lazy loaded just map your entity with lazy="false" and you won't need virtual members any more. If you need lazy loading, you can use a proxy interface with proxy="ProxyInterface".

清欢 2024-12-24 12:24:59

不久前我也有类似的需求,并使用了 CodeProject 上的这篇文章 作为模板。看起来效果很好。

我认为关键是不要从域对象中的 MembershipUser 继承,而是提供一种在域用户和成员用户之间进行转换的方法(我不相信我根本改变了这个函数):

    public MembershipUser GetMembershipUserFromUser (User usr) {
        MembershipUser u = new MembershipUser (this.Name, usr.Username, usr.Id, usr.Email, usr.PasswordQuestion, usr.Comment, usr.IsApproved, usr.IsLockedOut, usr.CreationDate, usr.LastLoginDate,
        usr.LastActivityDate, usr.LastPasswordChangedDate, usr.LastLockedOutDate);

        return u;
    }

I had a similar need a while back and used this article on CodeProject as a template. It seemed to work pretty well.

I think the key for this is to NOT inherit from MembershipUser in your domain object, but provide a way to translate between your domain user and a membership user (I don't believe I changed this function at all):

    public MembershipUser GetMembershipUserFromUser (User usr) {
        MembershipUser u = new MembershipUser (this.Name, usr.Username, usr.Id, usr.Email, usr.PasswordQuestion, usr.Comment, usr.IsApproved, usr.IsLockedOut, usr.CreationDate, usr.LastLoginDate,
        usr.LastActivityDate, usr.LastPasswordChangedDate, usr.LastLockedOutDate);

        return u;
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文