Usamos NH 2 y este ejemplo no funcionó para nosotros. (NO FUE desproxydo el tipo y el proxy izquierdo) tipo, ver abajo) se dice que 2 entidades con el mismo ID no son iguales, cuando uno de ellos es proxy (de COrganization) y otro no lo es (DOrganization) cuando tuvimos una jerarquía:..
class Organization
class AOrganization : Organization
class COrganization : Organization
{
public virtual COrganization GetConcrete()
{
return null;
}
}
class DOrganization : COrganization
{
public virtual COrganization GetConcrete()
{
return this;
}
}
AOrganization aOrganization;
COrganization cOrganization;
contract = new CContract(aOrganization, cOrganization as COrganization); //(COrganization)(cOrganization.GetConcrete()),
Así CContract tiene un campo de tipo COrganization. Con un regulador de
public class Contract: Entity <short>
{
public virtual COrganization COrganization
{
get { return cOrganization; }
protected internal set
{
if (cOrganization != null && value != cOrganization) // != calls ==, which calls Equals, which calls GetUnproxiedType()
throw new Exception("Changing organization is not allowed.");
}
cOrganization = value;
}
}
private COrganization cOrganization;
}
Construimos nuevo contrato, su constructor establece el campo COrganization apuntando a alguna organización. Luego llamamos a UnitOfWork.Commit, NH intentó establecer el campo de organización nuevamente (con la misma identificación), GetUnproxiedType funcionó incorrectamente, los valores nuevos y antiguos fueron reconocidos como no iguales, y se lanzó una excepción ...
Aquí es el lugar en el que mostró el error hasta:
var otherType = other.GetUnproxiedType();
var thisType = GetUnproxiedType();
return thisType.IsAssignableFrom(otherType) ||
otherType.IsAssignableFrom(thisType);
En depurador: othertype == COrganizationProxy - GetUnproxiedType fallidos ... thisType == DOrganization
COrganizationProxy y DOrganization uno de ellos heredando COrganization . Entonces no son IsAssignableFrom para el otro ...
¿Por qué este ejemplo funciona para usted?
Tal vez porque tenemos NH 2.0 o 2.1?
O debido a la sencilla "cOrganization como COrganization" en lugar de "(COrganization) (cOrganization.GetConcrete())"?
¿O porque tenemos la implementación de ==,! = E Igual no solo en Entidad, sino también en Organización?
public abstract class Organization : Entity<int>
{
public override bool Equals(object obj)
{
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
public static bool operator ==(Organization object1, Organization object2)
{
return AreEqual(object1, object2);
}
public static bool operator !=(Organization object1, Organization object2)
{
return AreNotEqual(object1, object2);
}
}
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();
}
/// This method added by me
/// For == overloading
protected static bool AreEqual<TEntity>(TEntity entity1, TEntity entity2)
{
if ((object)entity1 == null)
{
return ((object)entity2 == null);
}
else
{
return entity1.Equals(entity2);
}
}
/// This method added by me
/// For != overloading
protected static bool AreNotEqual<TEntity>(TEntity entity1, TEntity entity2)
{
return !AreEqual(entity1, entity2);
}
}
¿Puede adjuntar la implementación del método 'GetType()'? sin verlo, supongo que devuelve la clase subyacente "concreta" (por ejemplo, para ProductProxy, me imagino que debería devolver 'Producto' –
El productProxy es una clase proxy dinámica creada por NHibernate, así que no tengo ni idea de la puesta en práctica .. pensé que tal vez alguien con una idea de cómo NHibernate crea proxies serían capaces de ayudar .. también GetType() no es virtual, de modo parece ser que su aplicación como "nuevo" en la clase de proxy no tendría ningún efecto en todos .. –
Tengo el mismo libro y no soy un gran admirador de la implementación de Equals que se proporciona. Se basa demasiado en la persistencia de los objetos. El libro indica que si cualquiera de las entidades es transitoria (no guardada en el db) entonces este igual siempre devuelve falso. En primer lugar, creo que esto rompe la regla de ignorancia de persistencia y, en segundo lugar, qué sucede si quiero verificar la igualdad antes de guardar en la base de datos. Implemento parte de esto para la eficiencia (ch ecking the ids) pero aún implemento un "logical" Igual para todos mis objetos. – brainimus