Почему у меня возникла странная проблема при сравнении экземпляров объектов в IIS 7?
-
03-07-2019 - |
Вопрос
У меня действительно странная проблема, которую я не могу решить при сравнении объектов в IIS 7.Мы находимся в процессе развертывания нашего старого приложения на базе IIS 6 ASP.NET на 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, я не знаю, что с этим делать.
Это также общесистемная проблема всякий раз, когда я сравниваю два своих объекта entity.Таким образом, это может иметь какое-то отношение к оболочке 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
Это решение, которое сработало для меня:
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, чтобы заставить оператор "==" работать без перегрузки оператора.
Другие советы
Вы не объяснили, что proposalCountries
и proposalCountryServices
являются.Мне кажется, что ваш метод Equals работает просто отлично, но в IIS7 они содержат разные объекты - у вас есть два объекта с одинаковым идентификатором (поэтому Equals совпадает), но это разные объекты, поэтому == не совпадает.
Пожалуйста, предоставьте подробную информацию о том, как загружаются две коллекции - это, вероятно, и является причиной этого.
разница, которую я вижу, заключается в случае, если вы написали
c.Country == country.Country
и во втором случае это так
c.Country.Equals(country.Country))
так что я бы предположил, что в последнем случае ему это удается, потому что он сравнивает идентификаторы стран обоих объектов, в первом случае, однако, он сравнивает сами объекты.
Почему это работает под IE6, я не знаю...извините
Вы не используете ссылочное равенство (см. Ниже).
Object.Equals вызовет переопределенный метод Equals для вашего типа.
Я подозреваю, что вы извлекли разные экземпляры сущностей из разных DataContexts и добавили их в список, и, следовательно, используя переопределенное Equals, чтобы попытаться заставить его работать.
Обновить:
Извините, не уверен, используете ли вы LINQ2SQL.
Вероятно, вы могли бы устранить проблему, переопределив операторы ==/!=, но есть некоторые соображения, которые следует учитывать и при этом.
Обновление 2:
Чтобы понять, что я имею в виду, найдите оба экземпляра, которые вы считаете равными (именно там, где возникает эта проблема).Установите точку останова.Теперь перейдите &obj1 и введите и &obj2 и введите, вы заметите, что они указывают на разные адреса объектов.Сделайте это как в IIS 6, так и в 7.
Я не уверен, почему он ведет себя по-разному в IIS6 и IIS7, но я подозреваю, что тонкие различия в жизненном цикле страницы могут быть причиной того, что они не равны по ссылкам.
Обновление 3:
Вы работаете в классическом режиме в IIS7?Если нет, попробуйте сделать это.