Equals和GetHashCode中的延迟加载的NHibernate属性如何处理以下问题?我们正在使用延迟加载的NHibernate属性,每当我们调用Equals()或GetHashCode()时,任何使用的属性都将被延迟加载,可能导致一系列延迟加载操作。预加载可以用作替代方案,但我认为仅在特定情况下使用,而不是作为通用解决方案。典型情况如下:publicclassAbstractSaveableObject{[Id(0,Name="Id",UnsavedValue=null)][Generator(1,Class="native")]publicvirtuallong?id{得到;放;}}[Class(NameType=typeof(ClassA))]publicclassClassA:AbstractSavableObject{[Bag(0,Inverse=true,Cascade="none")][Key(1,Column="ClassA")][OneToMany(2、ClassType=typeof(ClassB))]publicvirtualICollectionClassBs{get;放;}}[Class(NameType=typeof(ClassB))]publicclassClassB:AbstractSavableObject{[ManyToOne(Column="ClassA")]publicvirtualClassAClassA{get;放;}[ManyToOne]publicvirtualClassCClassC{get;放;}[ManyToOne]publicvirtualClassDClassD{get;放;}publicvirtualboolEquals(ClassBother){if(ReferenceEquals(null,other)){returnfalse;}if(ReferenceEquals(this,other)){返回真;}returnEquals(other.ClassC,ClassC)&&Equals(other.ClassD,ClassD);}}为简单起见,省略了GetHashCode和Equals(object)实现。可以使用什么策略来解决这个问题?如果两个实体属于同一类型并且具有相同的主键,则它们是相等的。如果键有整数:像现在一样检查引用是否相等如果在某些基类中使用Equal方法,检查比较的类型是否相等。在这里你可能会遇到代理问题,我会回到那里检查主键是否相等——这不会导致任何延迟加载如果你有键的GUID:像现在一样检查引用是否相等检查主键是否相等——这不会导致任何延迟加载如果我有键的整数,我通常在我的实体的基类中有一个像这样的相等覆盖:publicvirtualboolEquals(EntityBaseother){if(other==null){returnfalse;}if(ReferenceEquals(other,this)){returntrue;}varotherType=NHibernateProxyHelper.GetClassWithoutInitializingProxy(other);varthisType=NHibernateProxyHelper.GetClassWithoutInitializingProxy(this);如果(!otherType.Equals(thisType)){返回false;等于(其他。Id,0);boolthisIsTransient=Equals(Id,0);如果(otherIsTransient||thisIsTransient)返回false;返回other.Id.Equals(Id);现在如果你使用表继承其他实体,你将面临以下问题:GetClassWithoutInitializingProxy如果是代理,将返回层次结构的基类,如果是加载的实体,则返回更具体的类型。在一个项目中,我通过遍历层次结构解决了这个问题,因此总是比较基类型——代理与否。在这些日子里,虽然我总是使用GUID作为密钥并按照此处所述进行操作:http://nhibernate.info/doc/patternsandpractices/identity-field-equality-and-hash-code.html然后没有代理类型不匹配问题。如果你使用身份平等,你应该能够在不触发加载的情况下访问密钥:publicvirtualboolEquals(ClassBother){if(ReferenceEquals(null,other)){returnfalse;}if(ReferenceEquals(this,other)){returntrue;}//需要检查nullIdreturnEquals(other.ClassC.Id,ClassC.Id)&&Equals(other.ClassD.Id,ClassD.Id);}你可以传入hashcode是瞬时缓存的hashcode来处理对象持久化前后的比较。这在Equals合约中留下了一个小缺口,因为现有瞬态对象之间的比较不会生成与同一对象的新检索版本相同的哈希码。公共抽象类实体{私有int?_cachedHashCode;公共虚拟intEntityId{得到;私有集;}publicvirtualboolIsTransient{get{returnEntityId==0;}}publicoverrideboolEquals(objectobj){if(obj==null){returnfalse;}varother=obj作为实体;返回等于(其他);}publicvirtualboolEquals(Entityother){if(other==null){returnfalse;}如果(IsTransient^other.IsTransient){返回假;}if(IsTransient&&other.IsTransient){returnReferenceEquals(this,other);}返回EntityId.Equals(other.EntityId);}publicoverrideintGetHashCode(){if(!_cachedHashCode.HasValue){_cachedHashCode=IsTransient?base.GetHashCode():EntityId.GetHashCode();}返回_cachedHashCode.Value;我使用以下规则:如果实体有一个POID属性(记住,不需要任何属性或任何成员,只需省略name="XX",不确定是否使用ActiveRecord或你使用的映射策略支持这个)如果实体没有POID属性,那你肯定需要一个自然的ID。使用自然id来实现平等和GetHashCode。如果你有一个多对一的自然id,而不是做FooProperty.Equals(other.FooProperty),使用FooProperty.Id.Equals(other.FooProperty.Id)。访问ID不会触发惰性引用的初始化。最后但并非最不重要的一点是,不赞成使用composite-id,并且非常不鼓励使用多对一键的composite-id。以上就是C#学习教程:Equals和GetHashCode中NHibernate属性延迟加载的全部内容,如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
