2016-06-29 18 views
-2

Ich versuche, (über LINQ) eine generische Liste abzufragen, und sie "handelt" so, als ob einige der Felder, auf denen ich mich befinde, nicht existieren. HierWarum erkennt meine LINQ-Abfrage Mitglieder einer allgemeinen Liste nicht?

ist der Code:

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

Es scheitert mit "‚string‘enthält keine Definition für‚Shortname‘und keine Erweiterungsmethode‚Shortname‘ein erstes Argument vom Typ‚string‘akzeptieren könnte gefunden werden (fehlt Ihnen eine Verwendungs-Richtlinie oder eine Assembly-Referenz?) "

Da ist anscheinend etwas falsch mit meiner LINQ-Syntax, aber ich weiß nicht was. Die generische Liste im Code definiert und erklärt, wie so:

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; 

Warum es keine Skrupel hat über „Preis“ noch beschwert sich über „Shortname“? Sie sind beide Mitglieder der Klasse "PriceVarianceSubsetData"

+2

Sie verwenden. Wählen Sie(), um nur die Price-Eigenschaft auszuwählen, d. H. Das ist die einzige verfügbare Eigenschaft. vielleicht sollten Sie die .Select an das Ende der Abfrage verschieben. – failedprogramming

+3

Verschieben Sie 'Select' an das Ende. –

Antwort

3

Linq-Abfragen werden angewendet, um in der Reihenfolge aufzulisten. In Ihrem Fall ist die Reihenfolge

  1. Aus Liste der PriceVarianceSubsetDataPrises
  2. Filterliste von Prices von ShortName nehmen ...

Als Ergebnis erhalten Sie einen Fehler.

Die korrekte Methode besteht darin, zuerst die erste Liste zu filtern und dann den gewünschten Wert auszuwählen.

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

Auch in diesem Fall als Ergebnis erhalten Sie die Liste aller Preise (IEnumerable<string>), die Ihre conditons erfüllen. Sie können nur einen Wert verwenden, indem Sie die Methode Single() verwenden. Die Wahl der Methode hängt vom gewünschten Verhalten ab. Sie sollten zwischen Single/First/SingleOrDefault/FirstOrDefault-Methoden wählen.

Und Price ist Zeichenfolge und Sie möchten doppelt. Sie sollten den Zeichenfolgenwert in double analysieren.

Der Code wird

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

Ist Single() gegenüber FirstOrDefault() vorzuziehen? Wenn ja warum? Es gibt Zeiten, in denen es keine Übereinstimmung gibt ... –

+1

@ B.ClayShannon '.Single()' bedeutet, dass Ihr Programm eine Ausnahme auslöst, wenn mehr als ein Element für alle Filter passt. Denken Sie zweimal darüber nach, es zu benutzen, und seien Sie sicher, dass es die einzige Möglichkeit ist. – Mafii

5

Das Problem, dass konfrontiert ist, sobald die Select Verfahren läuft, können Sie über Strings iterieren, nur die Auswahl zum Ende bewegen, und es wird

arbeiten

Sie sind auch viele unnötige Iteratoren, jede Linq Methode gibt einen Iterator

Schaffung würde ich

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