2016-06-29 1 views
-2

Я пытаюсь запросить (через LINQ) общий список, и он «действует», как будто некоторые из полей, в которых я «находится», не существует.Почему мой запрос LINQ не распознает членов общего списка?

Вот код:

private decimal GetPriceForMember_Code_Desc_Unit_Week(string member, string itemcode, string desc, string unit, int weeknum) 
{ 
    Decimal price = 0.00M; 
    if (unit == CRAFTWORKS_SC) 
    { 
     price = craftworksWeek1PVDSubsetList.Select(x => x.Price) 
      .Where(x => x.ShortName.Equals(member)) 
      .Where(x => x.Description.Equals(desc)) 
      .Where(x => x.WeekNum.Equals(weeknum)) 
      .Where(x => x.ItemCode.Equals(itemcode)); 
    } 
    //else if (unit == CHOPHOUSE) TODO: Finish 
    return price; 
} 

Это терпит неудачу с "„строки“не содержит определение для„сокращенного“, а метода расширения„сокращенного“принимающей первый аргумент типа„строка“ (вы не можете найти директиву по использованию или ссылку на сборку?) «

По-видимому, что-то не так с моим синтаксисом LINQ, но я не знаю, что. Общий список в коде определен и объявлен следующим образом:

public class PriceVarianceSubsetData 
{ 
    public String ShortName { get; set; } 
    public String ItemCode { get; set; } 
    public String Description { get; set; } //<= need this, too? 
    public String Price { get; set; } 
    public int WeekNum { get; set; } 
} 
. . . 
List<PriceVarianceSubsetData> craftworksWeek1PVDSubsetList = null; 

Почему это никаких сомнений по поводу «Цена» еще жалуется на «сокращенным»? Они оба являются членами класса «PriceVarianceSubsetData»

+2

um вы используете .Выберите(), чтобы выбрать только свойство Цена, т. Е. Это единственное свойство. возможно, вам следует переместить .Выбрать в конец запроса вместо – failedprogramming

+3

Переместить 'Выбрать' до конца. –

ответ

3

Запросы Linq применяются к списку по порядку. В вашем случае заказ

  1. Из списка PriceVarianceSubsetData принять Prises
  2. фильтр список Prices по ShortName ...

В результате вы получите ошибку.

Правильный способ - сначала отфильтровать исходный список, а затем выбрать нужное значение.

craftworksWeek1PVDSubsetList.Where(...).Select(); 

Кроме того, в этом случае в результате вы получите список всех цен (IEnumerable<string>), которые удовлетворяют ваши Условия работы. Вы можете использовать только одно значение, используя метод Single(). Выбор метода зависит от желаемого поведения. Вам следует выбрать методы Single/First/SingleOrDefault/FirstOrDefault.

И Price - это строка, и вы хотите двойной. Вы должны проанализировать значение строки в double.

Код будет

string stringPrice = craftworksWeek1PVDSubsetList 
     .Where(x => x.ShortName.Equals(member)) 
     .Where(x => x.Description.Equals(desc)) 
     .Where(x => x.WeekNum.Equals(weeknum)) 
     .Where(x => x.ItemCode.Equals(itemcode)) 
     .Select(x => x.Price) 
     .Single(); 
price = Double.Parse(stringPrice); 
+0

Является ли Single() предпочтительным для FirstOrDefault()? Если да, то почему? Бывают случаи, когда нет совпадения ... –

+1

@ B.ClayShannon '.Single()' означает, что ваша программа выдаст исключение, если для фильтра будет доступно более одного элемента. Подумайте дважды об использовании этого и убедитесь, что это единственная возможность. – Mafii

5

Проблема вы сталкиваетесь является то, что после того, как метод Select работает, вы итерация строк, просто переместите выбор до конца, и он будет работать

Вы также создает много ненужных итераторов, каждый метод Linq возвращает итератор

Я хотел бы попробовать

price = craftworksWeek1PVDSubsetList 
     .Where(x => x.ShortName.Equals(member) && 
        x.Description.Equals(desc) && 
        x.WeekNum.Equals(weeknum) && 
        x.ItemCode.Equals(itemcode)) 
     .Select(x => x.Price);