2

Except() メソッドに問題があります。差を返す代わりに、元のセットを返します。

Account クラスに IEquatable と IEqualityComparer を実装してみました。また、Account 用に別の IEqualityComparer クラスを作成してみました。

Except() メソッドがメインから呼び出されると、カスタムの Equals() メソッドが呼び出されないように見えますが、Count() を試してみると、カスタムの GetHashCode() メソッドが呼び出されました!

私はどこかで些細な間違いを犯したと確信しており、新鮮な目が私を助けてくれることを願っています.

主要:

IEnumerable<Account> everyPartnerID = 
    from partner in dataContext.Partners
    select new Account { IDPartner = partner.ID, Name = partner.Name };


IEnumerable<Account> hasAccountPartnerID = 
    from partner in dataContext.Partners
    from account in dataContext.Accounts
    where
        !partner.ID.Equals(Guid.Empty) &&
        account.IDPartner.Equals(partner.ID) &&
        account.Username.Equals("Special")
    select new Account { IDPartner = partner.ID, Name = partner.Name };

IEnumerable<Account> noAccountPartnerID = 
    everyPartnerID.Except(
        hasAccountPartnerID, 
        new LambdaComparer<Account>((x, y) => x.IDPartner.Equals(y.IDPartner)));

アカウント:

    public class Account : IEquatable<Account>
    {
        public Guid IDPartner{ get; set; }
        public string Name{ get; set; }

/*        #region IEquatable<Account> Members

        public bool Equals(Account other)
        {
            return this.IDPartner.Equals(other.IDPartner);
        }

        #endregion*/
    }

LambdaComparer:

   public class LambdaComparer<T> : IEqualityComparer<T>
    {
        private readonly Func<T, T, bool> _lambdaComparer;
        private readonly Func<T, int> _lambdaHash;

        public LambdaComparer(Func<T, T, bool> lambdaComparer) :
            this(lambdaComparer, o => o.GetHashCode())
        {
        }

        public LambdaComparer(Func<T, T, bool> lambdaComparer, Func<T, int> lambdaHash)
        {
            if (lambdaComparer == null)
                throw new ArgumentNullException("lambdaComparer");
            if (lambdaHash == null)
                throw new ArgumentNullException("lambdaHash");

            _lambdaComparer = lambdaComparer;
            _lambdaHash = lambdaHash;
        }

        public bool Equals(T x, T y)
        {
            return _lambdaComparer(x, y);
        }

        public int GetHashCode(T obj)
        {
            return _lambdaHash(obj);
        }
    }
4

4 に答える 4

8

基本的に、LambdaComparer関数を 1 つだけ渡すとクラスが壊れます。これは、他に何も提供しない場合、「ID ハッシュ コード」プロバイダーを使用するためです。ハッシュ コードは によって使用されてExceptおり、それが問題の原因です。

ここに 3 つのオプションがあります。

  1. 独自のメソッドを実装してから、できればそのようなものを含むMoreLINQExceptByに貢献してください。

  2. の別の実装を使用しIEqualityComparer<T>ます。MiscUtilProjectionEqualityComparerで使用できるクラスがあります。または、別の質問に投稿されているコードを使用できます。

  3. ハッシュに使用するラムダ式をLambdaComparerコードに渡します。

    new LambdaComparer<Account>((x, y) => x.IDPartner.Equals(y.IDPartner)),
                                x => x.IDPartner.GetHashCode());
    
于 2009-08-19T12:19:45.290 に答える
3

次のように等式パラメーターのみが指定されている場合に、LambdaComparerが機能するようにすばやく修正することもできます。

    public LambdaComparer(Func<T, T, bool> lambdaComparer) :
        this(lambdaComparer, o => 1)
    {
    }
于 2011-08-23T17:38:28.680 に答える