Pergunta

Eu tenho um problema muito estranho que não consigo resolver ao comparar objetos no IIS 7.Estamos no processo de implantação de nosso antigo aplicativo ASP.NET baseado em IIS 6 no IIS 7, mas temos esse problema de comparação de igualdade que não conseguimos resolver.

Deixe-me começar dizendo que tenho os mesmos assemblies e código em execução no IIS 6 e no IIS 7, porém a comparação dos objetos é diferente com o mesmo código no IIS 6 e no IIS 7.Aqui está um exemplo da aparência do meu 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();
    }
}

Eu tenho o seguinte código em uma página ASPX no IIS 6 e no 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)) %>
<% } %>

Aqui estão meus resultados:

IIS6:

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

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

IIS7:

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

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

Existe uma diferença entre o .NET 3.5 SP1 no Windows 2003 e o Windows 2008?Estou realmente sem saber qual poderia ser o problema.Alguém já experimentou um problema semelhante?

Atualização 1:

Para responder à pergunta de Jon.As duas coleções são carregadas usando NHibernate.Mas sinto que devo reiterar que tanto o IIS 6 quanto o IIS 7 estão usando o exatamente a mesma construção do aplicativo, portanto, a menos que NHibernate ou DynamicProxy2 estejam mudando a forma como as coisas são carregadas com base no Windows 2003 ou Windows 2007, sobre o qual não consegui encontrar nada no Google, não sei o que fazer com isso.

Esse também é um problema de todo o sistema sempre que estou comparando dois de meus objetos de entidade.Portanto, pode ter algo a ver com o wrapper DynamicProxy2, mas ambos os objetos são objetos Country e, dadas as substituições que criei, tudo deve funcionar da mesma forma no IIS 6 e no IIS 7.

Atualização 2:

Este parece ser um problema do DynamicProxy2 ou do NHibernate.Porque tentei o seguinte 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 %>

E tanto para o IIS 6 quanto para o IIS 7 o resultado foi, true, true, true, true, false.Veja minha resposta abaixo para saber o que fiz para resolver isso.

Atualização 3:

Isso também pode ter algo a ver com isso:Parece que você esqueceu de registrar o módulo http no Windsor Castle com IIS7

Foi útil?

Solução 4

Esta é a solução que funcionou para mim:

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 ou DynamicProxy estavam fazendo algum tipo de mágica no Windows 2003 para fazer com que o operador "==" funcionasse sem que o operador ficasse sobrecarregado.

Outras dicas

Você não explicou o que proposalCountries e proposalCountryServices são.Parece-me que seu método Equals está funcionando bem, mas no IIS7 eles contêm objetos distintos - você tem dois objetos com o mesmo ID (então Equals corresponde), mas são objetos distintos, então == não corresponde .

Forneça detalhes sobre como as duas coleções são carregadas - essa provavelmente é a causa disso.

a diferença que vejo é no caso de um que você escreveu

c.Country == country.Country

e no caso dois é

c.Country.Equals(country.Country))

então eu acho que no último caso ele teve sucesso porque está comparando os CountryIDs de ambos os objetos no primeiro caso, mas está comparando os próprios objetos.

Por que isso funciona no IE6 eu não sei...desculpe

Você não está usando igualdade referencial (veja abaixo).

Object.Equals chamará um método Equals substituído em seu tipo.

Eu suspeito que você retirou diferentes instâncias das entidades de diferentes DataContexts e as adicionou a uma lista e, portanto, usou um Equals substituído para tentar fazê-lo funcionar.

Atualizar:

Desculpe, não tenho certeza se você está usando LINQ2SQL.

Você provavelmente poderia corrigir o problema substituindo os operadores ==/!=, mas também há algumas considerações a serem feitas.

Atualização 2:

Para entender o que quero dizer, encontre as duas instâncias que você considera iguais (exatamente onde esse problema acontece).Defina um ponto de interrupção.Agora vá para &obj1 e digite e &obj2 e digite, você notará que eles apontam para endereços de objetos diferentes.Faça isso no IIS 6 e 7.

Não sei por que ele está se comportando de maneira diferente no IIS6 e no IIS7, mas suspeito que diferenças sutis no ciclo de vida da página possam ser a causa pela qual elas não são referencialmente iguais.

Atualização 3:

Você está executando no modo clássico no IIS7?Se não, tente fazer isso.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top