• NHibernate 透明代理的副作用


    一个bug调试了半天,才发现跟NHibernate透明代理有关。
    用测试代码验证了一下:
    ClassA有两个属性S1和S2,S1使用NHibernate持久化,S2不需要持久化。

    public class ClassA
    {
        
    private int _id;
        
    private string _s1;
        
    private string _s2;

        
    public virtual int ID
        {
            
    get { return this._id; }
            
    set { this._id = value; }
        }

        
    public virtual string S1
        {
            
    get { return this._s1; }
            
    set { this._s1 = value; }
        }

        
    internal virtual string S2
        {
            
    get { return this._s2; }
        }

        
    public virtual ClassA DoSomething(string s1, string s2)
        {
            
    this._s1 = s1;
            
    this._s2 = s2;
            
    return this;
        }
    }

    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="AA.CMS" assembly="aa.cms">
        
    <class name="ClassA" table="TableA">
            
    <id name="ID" >
                
    <column name="ID" sql-type="NUMBER(8,0)" not-null="true"/>
                
    <generator class="assigned" />
            
    </id>
            
    <property name="S1" >
                
    <column name="S1" sql-type="NVARCHAR2" length="25" not-null="false"/>
            
    </property>
        
    </class>
    </hibernate-mapping>

    public class ClassB
    {
        
    public string Get(ClassA a)
        {
            
    return a.S2;
        }
    }

    测试代码:
    [Test]
    public void Test()
    {
        ISession session 
    = TestSetup.GetSession();
        ClassA a1 
    = session.Load<ClassA>(1);
        ClassA a2 
    = a1.DoSomething("xxx""yyy");
        ClassB b 
    = new ClassB();

        DebugUtil.Output(a1.GetType().FullName);
        DebugUtil.Output(a1.S1 
    + " --- " + b.Get(a1));
        DebugUtil.Output(a2.GetType().FullName);
        DebugUtil.Output(a2.S1 
    + " --- " + b.Get(a2));
        session.Close();
    }

    输出结果:
    CProxyTypeAA_CMSClassACMS_NHibernate_ProxyINHibernateProxy1
    xxx ---
    AA.CMS.ClassA
    xxx --- yyy

    session.Load()返回的实体对象都是一个透明代理,当访问这个透明代理的public方法(NHibernate要求这些方法都是virtual类型的,用于从它继承实现透明代理对象)时,构造出实际的实体对象。
    问题表现在ClassB.Get()方法里面,它访问的是一个internal类型的属性S2,当传入的是一个透明代理时,internal的属性值S2无法获取到。可能是透明代理在internal类型的方法处理上有问题。

    如果想基于NHibernate使用充血模型,得好好注意透明代理的一些副作用了。
  • 相关阅读:
    Binary Tree Level Order Traversal
    Search a 2D Matrix
    Minimum Path Sum
    Remove Duplicates from Sorted Array II
    AngularJS 过滤器
    AngularJS 控制器
    AngularJS ng-model 指令
    AngularJS Scope(作用域)
    AngularJS 指令
    AngularJS表达式
  • 原文地址:https://www.cnblogs.com/RicCC/p/870685.html
Copyright © 2020-2023  润新知