Ich habe diesen Fehler in diesem linq-Ausdruck:
var naleznosci = (from nalTmp in db.Naleznosci
where nalTmp.idDziecko == idDziec
select new Payments
(
nalTmp.Dziecko.Imie,
nalTmp.Dziecko.Nazwisko,
nalTmp.Miesiace.Nazwa,
nalTmp.Kwota,
nalTmp.RodzajeOplat.NazwaRodzajuOplaty,
nalTmp.RodzajeOplat.TypyOplat.NazwaTypuOplaty,
nalTmp.DataRozliczenia,
nalTmp.TerminPlatnosci
)).ToList();
Irgendeine Idee, wie man dieses Problem löst? Ich versuche es mit einer beliebigen Ausdruckskombination ...: /
c#
linq-to-entities
netmajor
quelle
quelle
Antworten:
Ohne weitere Informationen zu "Zahlungen" hilft dies nicht viel. Vorausgesetzt, Sie möchten ein Zahlungsobjekt erstellen und einige seiner Eigenschaften basierend auf Spaltenwerten festlegen:
quelle
Wenn Sie Ihren Konstruktor weiterhin für die Initialisierung und nicht für Eigenschaften verwenden möchten (manchmal ist dieses Verhalten für Initialisierungszwecke erwünscht), führen Sie die Abfrage auf, indem Sie
ToList()
oder aufrufenToArray()
, und verwenden Sie dannSelect(…)
. Daher wird LINQ to Collections verwendet und die Einschränkung, dass Konstruktoren mit Parametern in nicht aufgerufen werden könnenSelect(…)
verschwindet.Ihr Code sollte also ungefähr so aussehen:
quelle
ToX()
, verwendenAsEnumerable()
.Nachdem ich diesen Fehler gerade selbst festgestellt habe, dachte ich, ich würde hinzufügen, dass wenn der
Payment
Typ a iststruct
, Sie auch auf denselben Fehler stoßen würden, dastruct
Typen keine parameterlosen Konstruktoren unterstützen.In diesem Fall
Payment
wird das Problem durch Konvertieren in eine Klasse und Verwenden der Objektinitialisierersyntax behoben.quelle
DateTime
(die eine Struktur ist) in meiner Abfrage, was zu demselben Fehler führt. Das Extrahieren in eine lokale Variable hat es für mich behoben. Danke für den Strukturhinweis.Wenn Sie wie ich sind und nicht für jede Abfrage, die Sie erstellen, Ihre Eigenschaften auffüllen müssen, gibt es eine andere Möglichkeit, dieses Problem zu lösen.
Zu diesem Zeitpunkt haben Sie eine IQueryable, die ein anonymes Objekt enthält. Wenn Sie Ihr benutzerdefiniertes Objekt mit einem Konstruktor füllen möchten, können Sie einfach Folgendes tun:
Jetzt kann Ihr benutzerdefiniertes Objekt (das zwei Objekte als Parameter verwendet) Ihre Eigenschaften nach Bedarf füllen.
quelle
Zuerst würde ich die Lösung mit vermeiden
Dies erfordert einen leeren Konstruktor und ignoriert die Kapselung, sodass Sie sagen, dass new Payments () eine gültige Zahlung ohne Daten ist. Stattdessen muss das Objekt abhängig von Ihrer Domain mindestens einen Wert und wahrscheinlich andere erforderliche Felder haben.
Es ist besser, einen Konstruktor für erforderliche Felder zu haben, aber nur die erforderlichen Daten mitzubringen:
quelle
Sie können versuchen, dasselbe zu tun, aber die Erweiterungsmethoden verwenden. Was ist der Anbieter der Datenbanknutzung?
quelle
Nur
ToList()
dieDbSet
vor derSelect
Anweisung .. die tatsächlicheDbSet
wird als Abfrage gespeichert, es ist noch nicht erfüllt. Nach dem Aufruf spielenToList()
Sie mit Objekten und können dann einen nicht standardmäßigen Konstruktor in der Abfrage verwenden.Nicht die effizienteste Art der Nutzungsdauer, aber eine Option für kleine Sets.
quelle
yeh, versuch es so ....
Dadurch wird Ihr Zahlungsobjekt mithilfe eines parameterlosen Konstruktors neu erstellt und anschließend die Eigenschaften initialisiert, die in geschweiften Klammern aufgeführt sind
{ }
quelle
()
Ihrer Information, das in den Payemnts wird nicht benötigt, daher kann es sein, "Neue Zahlungen auswählen {// Init-Werte}Zusätzlich zu den oben genannten Methoden können Sie es auch als Enumerable-Sammlung analysieren, z. B.:
Dies hat auch den zusätzlichen Vorteil, dass das Leben beim Erstellen eines anonymen Objekts wie folgt erleichtert wird:
Denken Sie jedoch daran, dass das Parsen einer Sammlung als Enumerable sie in den Speicher zieht, sodass sie ressourcenintensiv sein kann! Hier ist Vorsicht geboten.
quelle
Wenn Sie zum Initialisieren einen Konstruktor mit mehreren Objekten verwenden möchten, wird möglicherweise eine Fehlermeldung angezeigt, wenn Linq keine Werte zurückgibt.
Vielleicht möchten Sie so etwas tun:
quelle
Sorry für die Verspätung der Partei, aber ich nach dem Auffinden dieser , dachte ich, dass dies geteilt werden sollte, da es die sauberste, schnellste und auch speichersparendste Implementierung ist, die ich finden konnte.
An Ihr Beispiel angepasst würden Sie schreiben:
Die großen Vorteile hier (wie Damien Guard in den Kommentaren unter dem Link hervorhob) sind:
var foo = createPayments(bar);
sowie Nutzung über myIQueryable.ToPayments () möglich.quelle
Ich hatte heute das gleiche Problem und meine Lösung ähnelte der von Yoda aufgelisteten, funktioniert jedoch nur mit fließender Syntax.
Anpassen meiner Lösung an Ihren Code: Ich habe der Objektklasse die folgende statische Methode hinzugefügt
und aktualisierte dann die Basisabfrage auf Folgendes:
Dies entspricht logischerweise der Lösung von James Manning mit dem Vorteil, dass das Aufblähen der Elementinitialisierung auf das Klassen- / Datenübertragungsobjekt übertragen wird
Hinweis: Ursprünglich verwendete ich aussagekräftigere Namen als "Initializer", aber nachdem ich überprüft hatte, wie ich ihn verwendete, stellte ich fest, dass "Initilizer" ausreichend war (zumindest für meine Zwecke).
Schlussbemerkung:
Nachdem ich diese Lösung entwickelt hatte, dachte ich ursprünglich, es wäre einfach, denselben Code zu teilen und diesen anzupassen, um auch für die Abfragesyntax zu funktionieren. Ich glaube nicht mehr, dass dies der Fall ist. Ich denke, wenn Sie in der Lage sein möchten, diese Art der Kurzschriftkonstruktion zu verwenden, benötigen Sie eine Methode für jede (Abfrage, fließend) fließend wie oben beschrieben, die in der Objektklasse selbst vorhanden sein kann.
Für die Abfragesyntax wäre eine Erweiterungsmethode (oder eine Methode außerhalb der verwendeten Basisklasse) erforderlich. (da die Abfragesyntax eher ein IQueryable als ein T betreiben möchte)
Hier ist ein Beispiel dessen, was ich verwendet habe, um dies endlich für die Abfragesyntax zum Laufen zu bringen. (Yoda hat das bereits verstanden, aber ich denke, die Verwendung könnte klarer sein, weil ich es zuerst nicht verstanden habe.)
und die Verwendung
quelle
Obwohl es spät ist zu antworten, könnte es dennoch jemandem in Not helfen. Da LINQ to-Entitäten die parameterlosen Objektkonstruktionen nicht unterstützen. Die Projektionsmethoden für IEnumerable sind jedoch .
Konvertieren Sie also vor der Auswahl einfach Ihr IQueryable mit diesem Code in IEnumerable :
Es wird gut funktionieren. Es wird jedoch natürlich die Vorteile nativer Abfragen verlieren.
quelle
quelle