Почему у меня возникает странная проблема при сравнении экземпляров объектов в IIS 7? - PullRequest
0 голосов
/ 04 марта 2009

У меня действительно странная проблема, которую я не могу понять при сравнении объектов в IIS 7. Мы находимся в процессе развертывания нашего старого приложения ASP.NET на основе IIS 6 в IIS 7, однако у нас есть проблема сравнения на равенство что мы не можем понять,

Позвольте мне начать с того, что у меня одинаковые сборки и код, работающий как на IIS 6, так и на IIS 7, однако сравнение объектов отличается с одним и тем же кодом на IIS 6 и IIS 7. Вот пример из того, как выглядит мой объект:

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();
    }
}

У меня есть следующий код на странице ASPX как на IIS 6, так и на 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)) %>
<% } %>

Вот мои результаты:

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

Есть ли разница между .NET 3.5 SP1 в Windows 2003 и Windows 2008? Я действительно в недоумении, в чем может быть проблема. Кто-нибудь сталкивался с подобной проблемой?

Обновление 1:

Чтобы ответить на вопрос Джона. Две коллекции загружаются с использованием NHibernate. Но я чувствую, что должен повторить, что как IIS 6, так и IIS 7 используют точно такую ​​же сборку приложения, поэтому, если только NHibernate или DynamicProxy2 не изменят способ загрузки данных на основе Windows 2003 или Windows 2007, которые я Я не смог ничего найти в Google, я не знаю, что с этим делать.

Это также проблема всей системы, когда я сравниваю два моих объекта сущности. Так что это может иметь какое-то отношение к оболочке DynamicProxy2, но оба объекта являются объектами Country, и с учетом созданных мною переопределений все должно работать одинаково в IIS 6 и IIS 7.

Обновление 2:

Похоже, это проблема DynamicProxy2 или NHibernate. Потому что я попробовал следующий код:

<%
    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 %>

И для IIS 6, и для IIS 7 был получен результат true, true, true, true, false. Смотрите мой ответ ниже, чтобы узнать, что я сделал, чтобы решить эту проблему.

Обновление 3:

Это также могло иметь отношение к этому: Похоже, вы забыли зарегистрировать модуль http в Windsor Castle с IIS7

Ответы [ 4 ]

1 голос
/ 04 марта 2009

Вы не объяснили, что такое proposalCountries и proposalCountryServices. Мне кажется, что ваш метод Equals работает просто отлично, но в IIS7 они содержат разные объекты - у вас есть два объекта с одинаковым идентификатором (так что Equals соответствует), но это разные объекты, поэтому == не соответствует .

Пожалуйста, опишите подробно, как загружаются две коллекции - вероятно, это и есть причина.

0 голосов
/ 04 марта 2009

Это решение, которое сработало для меня:

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);
}

Судя по всему, NHibernate или DynamicProxy делали что-то волшебное в Windows 2003, чтобы заставить оператор "==" работать без перегрузки оператора.

0 голосов
/ 04 марта 2009

Вы не используете ссылочное равенство (см. Ниже).

Object.Equals вызовет переопределенный метод Equals для вашего типа.

Я подозреваю, что вы извлекли разные экземпляры сущностей из разных DataContexts и добавили его в список, и, следовательно, использовали переопределенный метод Equals, чтобы попытаться заставить его работать.

Обновление:

Извините, не уверен, используете ли вы LINQ2SQL.

Вероятно, вы могли бы решить эту проблему, переопределив операторы == /! =, Но есть некоторые соображения, которые также следует учитывать.

Обновление 2:

Чтобы понять, что я имею в виду, найдите оба случая, которые вы считаете равными (именно там, где возникает эта проблема). Установите точку останова. Теперь перейдите к & obj1 и введите и & obj2 и введите, вы заметите, что они указывают на разные адреса объектов. Сделайте это на IIS 6 и 7.

Я не уверен, почему он ведет себя по-разному в IIS6 и IIS7, но я подозреваю, что незначительные различия в жизненном цикле страницы могут быть причиной, по которой они не равны между собой.

Обновление 3:

Вы работаете в классическом режиме в IIS7? Если нет, попробуйте сделать это.

0 голосов
/ 04 марта 2009

Я вижу разницу в том случае, если вы написали

c.Country == country.Country

, а в случае два это

c.Country.Equals(country.Country))

поэтому я думаю, что в последнем случае он преуспевает, потому что он сравнивает идентификаторы CountryID обоих объектов в первом случае, но сам сравнивает объекты.

Почему это работает под IE6, я не знаю ... извините

...