Pregunta

Tengo un problema realmente extraño que no puedo resolver al comparar objetos en IIS 7. Estamos en el proceso de implementar nuestra antigua aplicación ASP.NET basada en IIS 6 en IIS 7, sin embargo, tenemos este problema de comparación de igualdad que parece que no podemos entender.

Permítanme comenzar diciendo que tengo los mismos ensamblajes y códigos que se ejecutan tanto en IIS 6 como en IIS 7, sin embargo, la comparación de los objetos difiere con el mismo código tanto en IIS 6 como en IIS 7. Aquí hay un ejemplo de cómo se ve mi objeto:

class Country : EntityBase {
    public int CountryID { get; set; }
    public string Name { get; set; }

    public override bool Equals(object obj) {
        if (obj == null || !(obj is Country))
            return false;

        Country c = (Country)obj;
        return CountryID == c.CountryID;
    }

    public override int GetHashCode() {
        return CountryID.GetHashCode();
    }
}

Tengo el siguiente código en una página ASPX tanto en IIS 6 como en IIS 7:

<% foreach(var country in proposalCountries) { %>
<%= country.Country.CountryID %>
<%= country.Country.CountryID.GetHashCode() %>
<%= country.Country.GetHashCode() %>

<%= proposalCountryServices.Count(c => c.Country == country.Country) %>
<%= proposalCountryServices.Count(c => (c.Country != null && country.Country != null) && c.Country.Equals(country.Country)) %>)
<%= proposalCountryServices.Count(c => Object.Equals(c.Country, country.Country)) %>
<% } %>

Aquí están mis resultados:

IIS 6:

100 <-- CountryID
100 <-- CountryID Hash Code
100 <-- Country Hash Code

1 <-- Something Found
1 <-- Something Found
1 <-- Something Found

IIS 7:

100 <-- CountryID
100 <-- CountryID Hash Code
100 <-- Country Hash Code

0 <-- Nothing Found
1 <-- Something Found
1 <-- Something Found

¿Hay alguna diferencia entre .NET 3.5 SP1 en Windows 2003 y Windows 2008? Realmente no sé cuál podría ser el problema. ¿Alguien ha experimentado un problema similar?

Actualización 1:

Para responder la pregunta de Jon. Las dos colecciones se cargan con NHibernate. Pero creo que debo reiterar que tanto IIS 6 como IIS 7 están utilizando la exacta misma compilación de la aplicación, por lo que a menos que NHibernate o DynamicProxy2 estén cambiando la forma en que se cargan las cosas en función de Windows 2003 o Windows 2007, que No he podido encontrar nada sobre Google, no sé qué hacer con él.

Este también es un problema de todo el sistema cuando comparo dos de mis objetos de entidad. Por lo tanto, podría tener algo que ver con el contenedor DynamicProxy2, pero ambos objetos son objetos Country y, dada la anulación que he creado, todo debería funcionar igual en IIS 6 e IIS 7.

Actualización 2:

Esto parece ser un problema de DynamicProxy2 o NHibernate. Porque probé el siguiente código:

<%
    var c1 = new ICost.Business.Entities.Country {
        CountryID = 100
    };
    var c2 = new ICost.Business.Entities.Country {
        CountryID = 100
    };
%>
<%= c1.CountryID == c2.CountryID %>
<%= c1.GetHashCode() == c2.GetHashCode() %>
<%= c1.Equals(c2) %>
<%= Object.Equals(c1, c2) %>
<%= c1 == c2 %>

Y para IIS 6 e IIS 7 el resultado fue, true , true , true , true , false . Vea mi respuesta a continuación para saber qué hice para resolver esto.

Actualización 3:

Esto también podría haber tenido algo que ver con eso: Parece que olvidó registrar el módulo http con Windsor Castle con IIS7

¿Fue útil?

Solución 4

Esta es la solución que funcionó para mí:

public static bool operator ==(BaseEntity a, BaseEntity b)
{
    return Object.Equals(a, b);
}

public static bool operator !=(BaseEntity a, BaseEntity b)
{
    return !Object.Equals(a, b);
}

Aparentemente, NHibernate o DynamicProxy estaban haciendo algún tipo de magia en Windows 2003 para obtener el " == " operador para trabajar sin el operador sobrecargado.

Otros consejos

No ha explicado qué son PropositionCountries y PropositionCountryServices . Me parece que su método Equals funciona bien, pero en IIS7 contienen objetos distintos: tiene dos objetos con la misma ID (por lo que Equals coincide) pero son objetos distintos, por lo que == no coincide .

Proporcione detalles sobre cómo se cargan las dos colecciones, es probable que sea la causa de ello.

la diferencia que veo es en caso de que hayas escrito

c.Country == country.Country

y en el caso dos es

c.Country.Equals(country.Country))

así que supongo que en el último caso tiene éxito porque está comparando los ID de país de ambos objetos en el primer caso, sin embargo, está comparando los objetos ellos mismos.

Por qué esto funciona bajo IE6 No lo sé ... lo siento

No está utilizando la igualdad referencial (ver más abajo).

Object.Equals llamará a un método Equals anulado en su tipo.

Sospecho que ha extraído diferentes instancias de las entidades de diferentes DataContexts, y las ha agregado a una lista y, por lo tanto, utiliza una Igual invalidada para intentar que funcione.

Actualización:

Lo siento, no estoy seguro si está utilizando LINQ2SQL.

Probablemente podría solucionar el problema anulando los operadores == /! =, pero también hay algunas consideraciones a tener en cuenta.

Actualización 2:

Para entender lo que quiero decir, encuentre las dos instancias que considere iguales (exactamente dónde ocurre este problema). Establecer un punto de interrupción. Ahora, vaya a & amp; obj1 e ingrese y & amp; obj2 e ingrese, notará que apuntan a diferentes direcciones de objetos. Haga esto en IIS 6 y 7.

No estoy seguro de por qué se comporta de manera diferente en IIS6 e IIS7, pero sospecho que diferencias sutiles en el ciclo de vida de la página podrían ser la causa de por qué no son referencialmente iguales.

Actualización 3:

¿Está ejecutando en modo clásico en IIS7? Si no, intente hacerlo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top