开启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代理接口而非实体类,避开基类方法的访问限制:
- 定义接口:
public interface ICustomMembershipUser { // 声明CustomMembershipUser的业务方法 string GetUsername(); DateTime GetCreationDate(); // 其他需要暴露的方法 }
- 让
CustomMembershipUser实现该接口:
public class CustomMembershipUser : MembershipUser, ICustomMembershipUser { // 实现接口方法 public string GetUsername() => this.UserName; public DateTime GetCreationDate() => this.CreationDate; // 自定义属性和方法 }
- 配置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
相关产品推荐
相关产品推荐

