2010-03-18 2 views
2

Доброе утро,Linq help using «Содержит»

Я пытаюсь использовать «Содержит», чтобы узнать, находится ли объект в коллекции. Когда я ломаюсь, я вижу, что объект действительно является частью коллекции, однако «Содержит», кажется, возвращает false, указывая, что элемент не находится в коллекции. Любая идея, что я делаю неправильно?

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; 
} 

Если объект не находится в коллекции, «DaysPaid» должен быть пустым. Есть идеи?

*** ОБНОВЛЕНИЕ PaymentTypeInfo - стандартный класс, созданный LinqToSql. Equals или GetHashCode были переопределены в этот момент. Вот его источник.

[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; 
      } 
     } 
    } 
} 

Спасибо, ~ ск в Сан-Диего

ответ

1

Возможно, вы работаете в вопросе равенства - Содержит() использует метод IEquatable.Equals, так что вы можете проверить, чтобы убедиться, что это происходит для возврата true для отдельных экземпляров класса PaymentTypeInfo.

3

EDIT: Как указал Ахмад, использование вашего условного оператора неверно. Тем не менее, вы даже не нуждаетесь в , чтобы использовать условный оператор здесь, так как одна из ветвей приводит к отсутствию операции. Просто используйте это:

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

Оригинальный ответ

Вы не показали каких-либо вещь о PaymentTypeInfo - это переопределить Equals и GetHashCode надлежащим образом? Если нет, проверка сдерживания будет выполняться с использованием ссылочного идентификатора, и очень маловероятно, чтобы ссылка в сеансе была такой же, как ссылка в репозитории.

Либо сделать PaymentTypeInfo переопределение Equals и GetHashCode, или передать соответствующий IEqualityComparer<PaymentTypeInfo> в метод Contains.

(Как SLaks упоминает в комментариях, в этом случае GetHashCode будет на самом деле не дозвонились - но вы всегда должны переопределить как Equals и GetHashCode или ни один из них, если вы сделать переопределить их, вы должны сделать это в последовательным образом.)

+0

'Содержит' не вызывает' GetHashCode'. (Хотя многие другие методы делают) – SLaks

+1

Если вы переопределите Equals(), рекомендуется переопределить GetHashCode(). Компилятор предупреждает вас, если вы этого не сделаете. –

+0

Я, конечно, не предлагаю вам переопределить 'Equals' без' GetHashCode'. (Хотя предупреждение от FxCop, а не компилятора) – SLaks

2

Если payType переопределяет Equals или не указать IEqualityComparer, Contains сравнит по ссылке.

Ваша коллекция, вероятно, содержит другой экземпляр класса, который является логически эквивалентным.

0

Можете ли вы разместить источник класса PaymentType? Я вполне уверен, что этот тип не предоставляет семантики на основе значений, поэтому метод Contains вынужден прибегать к использованию равенства идентичности (что не дает вам желаемых результатов).

Если это так, вы можете быть заинтересованы в этих статьях я писал на эту тему:

1

Каждый пост до сих пор имеет действительную точку; в зависимости от используемого типа Contains может оказаться недостаточным. Я обращаюсь к другой части вашего вопроса, хотя:

Если объект не находится в коллекции «DaysPaid» должен быть нулевым. Любые идеи?

Как насчет переключения порядка трехмерных значений оператора в соответствии с приведенным выше утверждением? Используйте это:

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

Вместо этого:

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

Если оператор вычисляет false 2-й пункт будет использоваться, так что сделайте это null. Структура:

logic statement ? true : false 
+0

Doh - я был зафиксирован на части Содержит :) –

+0

@Ahmad: Фактически, глядя на это, ясно видно, что условный оператор вообще не требуется , См. Мой обновленный ответ. –

+0

@Jon: согласился, что чище :) –