我有一个非常奇怪的问题,我无法通过比较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上的.NET 3.5 SP1与Windows 2008之间有区别吗?我真的不知道问题是什么。有没有人遇到过类似的问题?

更新1:

回答Jon的问题。这两个集合使用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:

这也可能与它有关: 您似乎忘了在Windsor Castle上注册带有IIS7的http模块

有帮助吗?

解决方案 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中它们包含不同的对象 - 你有两个具有相同ID的对象(所以Equals匹配)但是它们是不同的对象,所以==不匹配

请详细说明两个馆藏是如何加载的 - 这可能是它的原因。

我看到的区别在于你写的一个

c.Country == country.Country

如果是两个,那么

c.Country.Equals(country.Country))

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

为什么这在IE6下工作我不知道......对不起

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

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

我怀疑你已从不同的DataContexts中提取出不同的实体实例,并将其添加到列表中,因此使用重写的Equals尝试使其工作。

更新

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

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

更新2:

要明白我的意思,找到你认为相同的两个实例(确切地说这个问题发生的地方)。设置断点。现在,转到&amp; obj1并输入&amp; obj2并输入,您会注意到它们指向不同的对象地址。在IIS 6和7上执行此操作。

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

更新3:

您是否在IIS7中以经典模式运行?如果没有,请尝试这样做。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top