IIS 7でオブジェクトインスタンスを比較するときに奇妙な問題が発生するのはなぜですか?
-
03-07-2019 - |
質問
IIS 7でオブジェクトを比較するとわからない、本当に奇妙な問題があります。IIS7に古い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:
ジョンの質問に答えるため。 2つのコレクションは、NHibernateを使用してロードされます。ただし、IIS 6とIIS 7の両方がアプリケーションの exact same build を使用しているため、NHibernateまたはDynamicProxy2がWindows 2003またはWindows 2007に基づいて物事のロード方法を変更しない限り、繰り返しますが私はグーグルで何も見つけることができませんでした。何を作るべきかわかりません。
これは、2つのエンティティオブジェクトを比較するときのシステム全体の問題でもあります。したがって、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モジュールをIIS7のWindsor Castleに登録するのを忘れたようです
解決 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で&quot; ==&quot;を取得するために何らかの魔法をかけていました。オーバーロードされている演算子を処理する演算子。
他のヒント
proposalCountries
および proposalCountryServices
が何であるかを説明していません。 Equalsメソッドはうまく機能しているように見えますが、IIS7では異なるオブジェクトが含まれています-同じIDを持つ2つのオブジェクトを持っているので(Equalsが一致します)、それらは異なるオブジェクトなので、==は一致しません。
2つのコレクションがどのようにロードされるかについて詳細を教えてください-それが原因である可能性が高いです。
私が見る違いは、あなたが書いたものの場合です
c.Country == country.Country
そしてケース2の場合は
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のクラシックモードで実行していますか?そうでない場合は、そうしてみてください。