You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

开启Lazy加载后,继承MembershipUser的实体触发NHibernate代理异常如何解决?

解决NHibernate懒加载继承MembershipUser时的InvalidProxyTypeException问题

问题原因

NHibernate生成懒加载代理时,要求目标类的非private方法必须是public/protected virtual或protected internal virtual,但System.Web.Security.MembershipUser中的Update、GetPassword等核心方法是internal virtual,无法修改基类的访问修饰符,导致代理生成失败。

可行解决方案

1. 关闭该实体的懒加载

直接禁用CustomMembershipUser的懒加载,绕过代理生成逻辑:

  • XML映射配置:
<class name="CustomMembershipUser" table="Users" lazy="false">
  <!-- 其他映射配置 -->
</class>
  • Fluent NHibernate配置:
public class CustomMembershipUserMap : ClassMap<CustomMembershipUser>
{
    public CustomMembershipUserMap()
    {
        Table("Users");
        Not.LazyLoad(); // 关闭懒加载
        // 其他映射配置
    }
}

2. 用接口代理替代类代理

定义一个包含业务方法的接口,让NHibernate代理接口而非实体类,避开基类方法的访问限制:

  1. 定义接口:
public interface ICustomMembershipUser
{
    // 声明CustomMembershipUser的业务方法
    string GetUsername();
    DateTime GetCreationDate();
    // 其他需要暴露的方法
}
  1. 让CustomMembershipUser实现该接口:
public class CustomMembershipUser : MembershipUser, ICustomMembershipUser
{
    // 实现接口方法
    public string GetUsername() => this.UserName;
    public DateTime GetCreationDate() => this.CreationDate;
    // 自定义属性和方法
}
  1. 配置NHibernate使用接口代理:
  • XML映射:
<class name="ICustomMembershipUser" table="Users" proxy-interface="ICustomMembershipUser">
  <!-- 映射接口对应的实体属性 -->
</class>
  • Fluent NHibernate:
public class CustomMembershipUserMap : ClassMap<CustomMembershipUser>
{
    public CustomMembershipUserMap()
    {
        Table("Users");
        Proxy<ICustomMembershipUser>(); // 指定代理接口
        // 其他映射配置
    }
}

3. 改用组合模式替代继承

不再让CustomMembershipUser继承MembershipUser,而是将MembershipUser作为内部属性持有,避免继承带来的代理冲突:

public class CustomMembershipUser
{
    public virtual int Id { get; set; }
    public virtual string Username { get; set; }
    // 其他自定义属性

    // 持有MembershipUser实例
    public MembershipUser MembershipUser { get; set; }

    // 封装MembershipUser的方法
    public void Update() => MembershipUser.Update();
    public string GetPassword() => MembershipUser.GetPassword();
}

这种方式下,NHibernate只代理CustomMembershipUser本身,内部的MembershipUser由自己管理,不受NHibernate代理规则限制。

内容的提问来源于stack exchange,提问作者Dark_Knight

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 22:10:11