Nhibernate.3.0.cookbook Chapter Fifth section setting up a base entity class

Source: Internet
Author: User

Setting up a base entity class
Set the base class for an entity class

In this section, I'll show you how to set up a common base class for our entity classes.

Preparatory work

Complete the previous task

How to Do

1. In Entity.cs, enter the following code for our entity class:

Public abstract class Entity<tid>
{
Public virtual TId Id {get; protected set;}
public override bool Equals (object obj)
{
Return Equals (obj as entity<tid>);
}
private static bool Istransient (Entity<tid> obj)
{
return obj! = null &&
Equals (obj. Id, Default (TId));
}
Private Type Getunproxiedtype ()
{
return GetType ();
}
Public virtual bool Equals (entity<tid> Other)
{
if (other = = null)
return false;
if (ReferenceEquals (this, other))
return true;
if (! Istransient (This) &&
! Istransient (Other) &&
Equals (Id, other. ID))
{
var othertype = other. Getunproxiedtype ();
var thistype = Getunproxiedtype ();
Return Thistype.isassignablefrom (othertype) | |
Othertype.isassignablefrom (Thistype);
}
return false;
}
public override int GetHashCode ()
{
if (Equals (Id, Default (TID)))
Return base. GetHashCode ();
return Id.gethashcode ();
}
}

2. In this file, we add another additional entity class, the code is as follows:

Public abstract class Entity:entity<guid>
{
}

Analysis principle

NHibernate need to rely on the Equals method for equality judgment. The method is defined by default in the System.Object class, which uses referential equality judgments in reference types (that is, the same memory address is considered equal), that is, X.equals (y) is true only if X and Y point to the same object instance. This default behavior works well in most cases.

To support lazy loading, NHibernate uses proxy objects. As we have learned before, these proxy objects are actually subclasses of real entity classes, and in order to support lazy loading, each of its members has been rewritten.

These proxy objects, in your application, this defaultEqualsThe behavior of the method can lead to some implicit and unexpectedBug。 An application should be unknowingly and transparently used for proxy objects, so we expect a proxy object and a real object if they describe the same entity object,Then they are supposed to be equal. If aProductObject thatIDIs8AnotherProductObject thatIDAlso8, or have an agent'sProductObject thatIDIs8, we should assume that the three objects are equal and have equivalence. To make them equal, we must override the defaultEqualsmethod to change the default behavior of the method(Determine equality by memory address)。 On top of USEntitybase class, we rewrite theEqualsmethod is used to make the method based on thePOIDTo determine equality. InEquals (Object obj)method, we simply call its overloaded methodEquals (entity<tid> other), try to putObjectType is converted toEntityType, if the conversion fails, theNULLValue is passed as a parameter to theEquals (entity<tid> Other)method, if the parameter OtherThe value isNULL, then the two objects are not equal. There are two kinds of cases, first,x.equals (NULL)return foreverfalseSecondsomeentity.equals (notanentity)also returnsfalse。 Next, we compare the reference addresses of both, obviously, if the variables of both refer to the same instance object(Same memory address)Then they must be equal. IfReferenceEquals (This,Other )Returned is thetrue,Then we also returntrue。

Next, we compare the ID and the default ID value to determine if the entity object is a temporary state, and a temporary object is an object that has not been persisted to the database. The default (TID) always returns the value of the TId , and for the Guid , its default value is guid.empty, for string And all other reference types, their default value is null, and for numeric types, the default value is 0. If the Id attribute is equal to its default value, the entity object is in a temporary state. If one or two entities are in a temporary state, we think they must be unequal ( if more than one object in the two objects being compared is in a temporary state, they must not be equal )and need to return false.

If the entity objects are persisted and they all have poid, we can determine the equality by comparing their poid values. If the poid is not equal, we assume that the two entity objects to be compared are unequal (not equal) and we return false.

Finally, we have to make a final judgment. We know that so far, the objects to be compared are definitely in a persistent state, and they all have the same ID value, but that doesn't prove to be equal. If a actorrole entity has the same poid value as a product entity, it is considered equal if it is just the above code. Our final judgment is to compare the types of the two, and if one of the types derives another type, we think they are equal.

If the other parameter is a proxy object for product and it describes a book entity, and the real book instance describes the same object, then this. Equals (Other) should return true because they all describe the same entity object. Unfortunately, however, other. GetType () does not return product, but instead returns ProductProxy12398712938, typeof (ProductProxy12398712938). IsAssignableFrom (typeof (book)) will result in false, in which case our Equals method will not be feasible. Because of this, we need to use other. The Getunproxiedtype () method, which returns the actual entity type through the proxy layer, because typeof (Product). IsAssignableFrom (typeof (book)) returns True, so our equals implementation can work well.

Because we have overridden the Equals method, we must also rewrite the GetHashCode method, which is also required by the. NET Framework Framework specification. If X. Equals (y), then X. GetHashCode () and Y. GetHashCode () should return the same value, which in turn is not required (if X. GetHashCode () and Y. GetHashCode () returns the same value, X. Equals (y) can return false), and X and Y can also share a hash code when they are not equal. In our entity base class, we simply use the hash code value of the ID.

Supplemental knowledge

For more knowledge about equals and GetHashCode, see the MSDN documentation for Http://msdn.microsoft.com/en-us/library/system. Object.aspx.

Add:

1. In the Mapping collection of section fourth, the processing of the Iset collection we have mentioned the need to rewrite the Equals and GetHashCode methods, and to determine whether an element already exists in Iset requires the use of equals.

2. In the above generic type, if the TID is also a reference type, it must also override its equals and GetHashCode methods.

Nhibernate.3.0.cookbook Chapter Fifth section setting up a base entity class

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.