开发者

Linq help using "Contains"

开发者 https://www.devze.com 2022-12-23 03:35 出处:网络
Good Morning All, I\'m trying to use \"Contains\" to see if an object is within the collection. When I break I can see that the object is indeed part of the collection however \"Contains\" seems to b

Good Morning All,

I'm trying to use "Contains" to see if an object is within the collection. When I break I can see that the object is indeed part of the collection however "Contains" seems to be returning false indicating the item is not in the collection. Any idea what I'm doing wrong开发者_如何学JAVA?

if(HttpContext.Current.Session["AutoPayTypes"] != null)
{
    var autopays = HttpContext.Current.Session["AutoPayTypes"] as List<PaymentTypeInfo>;
    char? coverageProductLine = null;

    if(entityProps.ContainsKey("CoverageProductLine"))
    {
       coverageProductLine = (char?)entityProps["CoverageProductLine"];
    }

    var paymentTypeInfoRepository = new PaymentTypeInfoRepository();
    var payType = paymentTypeInfoRepository.GetPaymentTypeInfo(paymentAdd.PayType,
    coverageProductLine);

    if (autopays != null && payType != null)
        paymentAdd.DaysPaid = autopays.Contains(payType) ? null : paymentAdd.DaysPaid;
}

If the object is not in the collection the "DaysPaid" needs to be null. Any ideas?

***UPDATE PaymentTypeInfo is a standard LinqToSql generated class. Equals nor GetHashCode has been overridden at this point. Here is it's source.

[Table(Name="dbo.S_OptPaymentType")]
public partial class PaymentTypeInfo
{

    private string _PaymentId;

    private string _PaymentCode;

    private System.Nullable<char> _CoverageType;

    private string _ActionCode;

    private System.Nullable<char> _PaymentType;

    private string _BenAction;

    private System.Nullable<char> _BenPremDisFlag;

    private string _APNextToLastAct;

    private string _APLastAct;

    public PaymentTypeInfo()
    {
    }

    [Column(Storage="_PaymentId", DbType="Char(3) NOT NULL", CanBeNull=false)]
    public string PaymentId
    {
        get
        {
            return this._PaymentId;
        }
        set
        {
            if ((this._PaymentId != value))
            {
                this._PaymentId = value;
            }
        }
    }

    [Column(Storage="_PaymentCode", DbType="Char(2) NOT NULL", CanBeNull=false)]
    public string PaymentCode
    {
        get
        {
            return this._PaymentCode;
        }
        set
        {
            if ((this._PaymentCode != value))
            {
                this._PaymentCode = value;
            }
        }
    }

    [Column(Storage="_CoverageType", DbType="Char(1)")]
    public System.Nullable<char> CoverageType
    {
        get
        {
            return this._CoverageType;
        }
        set
        {
            if ((this._CoverageType != value))
            {
                this._CoverageType = value;
            }
        }
    }

    [Column(Storage="_ActionCode", DbType="VarChar(3)")]
    public string ActionCode
    {
        get
        {
            return this._ActionCode;
        }
        set
        {
            if ((this._ActionCode != value))
            {
                this._ActionCode = value;
            }
        }
    }

    [Column(Name="PaymentType", Storage="_PaymentType", DbType="Char(1)")]
    public System.Nullable<char> PaymentType
    {
        get
        {
            return this._PaymentType;
        }
        set
        {
            if ((this._PaymentType != value))
            {
                this._PaymentType = value;
            }
        }
    }

    [Column(Storage="_BenAction", DbType="VarChar(3)")]
    public string BenAction
    {
        get
        {
            return this._BenAction;
        }
        set
        {
            if ((this._BenAction != value))
            {
                this._BenAction = value;
            }
        }
    }

    [Column(Storage="_BenPremDisFlag", DbType="Char(1)")]
    public System.Nullable<char> BenPremDisFlag
    {
        get
        {
            return this._BenPremDisFlag;
        }
        set
        {
            if ((this._BenPremDisFlag != value))
            {
                this._BenPremDisFlag = value;
            }
        }
    }

    [Column(Storage="_APNextToLastAct", DbType="VarChar(3)")]
    public string APNextToLastAct
    {
        get
        {
            return this._APNextToLastAct;
        }
        set
        {
            if ((this._APNextToLastAct != value))
            {
                this._APNextToLastAct = value;
            }
        }
    }

    [Column(Storage="_APLastAct", DbType="VarChar(3)")]
    public string APLastAct
    {
        get
        {
            return this._APLastAct;
        }
        set
        {
            if ((this._APLastAct != value))
            {
                this._APLastAct = value;
            }
        }
    }
}

Thanks, ~ck in San Diego


EDIT: As Ahmad pointed out, your conditional operator usage is incorrect. However, you don't even need to use the conditional operator here, as one of the branches results in a no-op. Just use this:

if (autopays != null && payType != null && !autopays.Contains(payType))
{
    paymentAdd.DaysPaid = null;
}

Original answer

You haven't shown any thing about PaymentTypeInfo - does it override Equals and GetHashCode appropriately? If not, the containment check will be performed using reference identity, and it's very unlikely that the reference in the session is the same as the reference in the repository.

Either make PaymentTypeInfo override Equals and GetHashCode, or pass an appropriate IEqualityComparer<PaymentTypeInfo> into the Contains method.

(As SLaks mentions in the comments, in this case GetHashCode won't actually get called - but you should always override both Equals and GetHashCode or neither of them; if you do override them, you should do so in a consistent manner.)


Unless payType overrides Equals or you specify an IEqualityComparer, Contains will compare by reference.

Your collection probably contains a different instance of the class which is logically equivalent.


It's possible you're running into an equality issue - Contains() uses the IEquatable.Equals method, so you might check to make sure that that's going to return true for separate instances of the PaymentTypeInfo class.


Every post so far has a valid point; depending on the type being used Contains may not suffice. I am addressing a different part of your question though:

If the object is not in the collection the "DaysPaid" needs to be null. Any ideas?

How about switching the order of your ternary operator values to match the above statement? Use this:

paymentAdd.DaysPaid = autopays.Contains(payType) ? paymentAdd.DaysPaid : null;

Instead of this:

paymentAdd.DaysPaid = autopays.Contains(payType) ? null : paymentAdd.DaysPaid;

If the statement evaluates to false the 2nd item will be used, so make it null. The structure is:

logic statement ? true : false


Can you post the source of the PaymentType class? I am fairly certain that this type does not provided value-based semantics so the Contains method is forced to resort to using identity equality (which is not giving you the results you want).

If this is the case you may be interested in these articles I wrote on this topic:

  • All types are not compared equally
  • All types are not compared equally (part 2)
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号