0

我有一个非常奇怪的问题,我无法通过比较 IIS 7 上的对象来解决。我们正在在 IIS 7 上部署基于 IIS 6 的旧 ASP.NET 应用程序,但是我们有这个相等比较问题,我们可以似乎没有弄清楚。

首先让我说我在 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();
    }
}

我在 IIS 6 和 IIS 7 的 ASPX 页面中都有以下代码:

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

Windows 2003 和 Windows 2008 上的 .NET 3.5 SP1 有区别吗?我真的不知道问题可能是什么。有没有人遇到过类似的问题?

更新1:

回答乔恩的问题。这两个集合是使用 NHibernate 加载的。但我觉得我应该重申 IIS 6 和 IIS 7 都使用完全相同的应用程序构建,所以除非 NHibernate 或 DynamicProxy2 正在改变基于 Windows 2003 或 Windows 2007 的加载方式,我无法做到在谷歌上找到任何东西,我不知道该怎么做。

每当我比较我的两个实体对象时,这也是一个系统范围的问题。所以它可能与 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, . 请参阅下面的答案,了解我为解决此问题所做的工作。truefalse

更新 3:

这也可能与它有关: 看起来您忘记使用 IIS7 向 Windsor Castle 注册 http 模块

4

4 回答 4

1

你还没有解释什么proposalCountriesproposalCountryServices是。在我看来,您的 Equals 方法工作得很好,但在 IIS7 中它们包含不同的对象 - 您有两个具有相同 ID 的对象(因此 Equals 匹配)但它们是不同的对象,所以 == 不匹配.

请详细说明这两个集合是如何加载的——这可能是它的原因。

于 2009-03-04T17:39:38.007 回答
0

我看到的区别是你写的一个

c.Country == country.Country

如果是两个,它是

c.Country.Equals(country.Country))

所以我猜想在后一种情况下他成功了,因为他在第一种情况下比较了两个对象的 CountryID,但是他正在比较对象本身。

为什么这在 IE6 下有效我不知道......对不起

于 2009-03-04T17:15:29.483 回答
0

您没有使用引用相等(见下文)。

Object.Equals 将在您的类型上调用重写的 Equals 方法。

我怀疑您已经从不同的 DataContexts 中提取了实体的不同实例,并将其添加到列表中,因此使用覆盖的 Equals 来尝试使其工作。

更新:

抱歉,不确定您是否使用的是 LINQ2SQL。

您可能可以通过覆盖 ==/!= 运算符来解决此问题,但也需要考虑一些因素。

更新 2:

要理解我的意思,请找到您认为相等的两个实例(正是发生此问题的位置)。设置断点。现在,进入 &obj1 和 enter 和 &obj2 并进入,你会注意到它们指向不同的对象地址。在 IIS 6 和 7 上执行此操作。

我不确定为什么它在 IIS6 和 IIS7 上的行为不同,但我怀疑页面生命周期中的细微差别可能是它们在引用上不相等的原因。

更新 3:

你是在 IIS7 的经典模式下运行的吗?如果没有,请尝试这样做。

于 2009-03-04T17:17:47.683 回答
0

这是对我有用的解决方案:

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 下做了某种魔术,以使“==”运算符在运算符过载的情况下正常工作。

于 2009-03-04T18:47:06.550 回答