Aus mehreren Gründen, über die ich nicht sprechen kann, definieren wir eine Ansicht in unserer SQL Server 2005-Datenbank wie folgt:
CREATE VIEW [dbo].[MeterProvingStatisticsPoint]
AS
SELECT
CAST(0 AS BIGINT) AS 'RowNumber',
CAST(0 AS BIGINT) AS 'ProverTicketId',
CAST(0 AS INT) AS 'ReportNumber',
GETDATE() AS 'CompletedDateTime',
CAST(1.1 AS float) AS 'MeterFactor',
CAST(1.1 AS float) AS 'Density',
CAST(1.1 AS float) AS 'FlowRate',
CAST(1.1 AS float) AS 'Average',
CAST(1.1 AS float) AS 'StandardDeviation',
CAST(1.1 AS float) AS 'MeanPlus2XStandardDeviation',
CAST(1.1 AS float) AS 'MeanMinus2XStandardDeviation'
WHERE 0 = 1
Die Idee ist, dass das Entity Framework eine Entität basierend auf dieser Abfrage erstellt, was es jedoch tut, aber es mit einem Fehler generiert, der Folgendes angibt:
Warnung 6002: In der Tabelle / Ansicht 'Keystone_Local.dbo.MeterProvingStatisticsPoint' ist kein Primärschlüssel definiert. Der Schlüssel wurde abgeleitet und die Definition als schreibgeschützte Tabelle / Ansicht erstellt.
Und es wird entschieden, dass das Feld CompletedDateTime dieser Entitätsprimärschlüssel ist.
Wir verwenden EdmGen, um das Modell zu generieren. Gibt es eine Möglichkeit, dass das Entity-Framework kein Feld dieser Ansicht als Primärschlüssel enthält?
quelle
Ich konnte dies mit dem Designer lösen.
Ich musste meine Ansicht nicht ändern, um die Problemumgehungen ISNULL, NULLIF oder COALESCE zu verwenden. Wenn Sie Ihr Modell aus der Datenbank aktualisieren, werden die Warnungen erneut angezeigt, verschwinden jedoch, wenn Sie VS schließen und erneut öffnen. Die im Designer vorgenommenen Änderungen bleiben erhalten und werden von der Aktualisierung nicht beeinflusst.
quelle
Stimmen Sie mit @Tillito überein, aber in den meisten Fällen wird der SQL-Optimierer verschmutzt und es werden keine richtigen Indizes verwendet.
Es mag für jemanden offensichtlich sein, aber ich habe Stunden damit verbracht, Leistungsprobleme mit der Tillito-Lösung zu lösen. Nehmen wir an, Sie haben den Tisch:
und Ihre Ansicht ist so etwas
Das SQL-Optimierungsprogramm verwendet nicht den Index ix_customer und führt einen Tabellenscan für den Primärindex durch.
Sie nutzen
Dadurch wird MS SQL (mindestens 2008) den richtigen Index in den Plan aufnehmen.
Wenn
quelle
Diese Methode funktioniert gut für mich. Ich verwende ISNULL () für das Primärschlüsselfeld und COALESCE (), wenn das Feld nicht der Primärschlüssel sein soll, sondern auch einen nicht nullbaren Wert haben soll. Dieses Beispiel liefert ein ID-Feld mit einem nicht nullbaren Primärschlüssel. Die anderen Felder sind keine Schlüssel und haben (Null) als Nullable-Attribut.
Wenn Sie wirklich keinen Primärschlüssel haben, können Sie einen fälschen, indem Sie mit ROW_NUMBER einen Pseudoschlüssel generieren, der von Ihrem Code ignoriert wird. Beispielsweise:
quelle
NEWID() as id
, aber es ist die gleiche Idee. Und es gibt legitime Anwendungsfälle - zum Beispiel, wenn Sie eine schreibgeschützte Ansicht haben. Hässlich, EF, hässlich.Der aktuelle Entity Framework-EDM-Generator erstellt einen zusammengesetzten Schlüssel aus allen nicht nullbaren Feldern in Ihrer Ansicht. Um die Kontrolle darüber zu erlangen, müssen Sie die Ansicht und die zugrunde liegenden Tabellenspalten ändern und die Spalten auf null setzen, wenn Sie nicht möchten, dass sie Teil des Primärschlüssels sind. Das Gegenteil ist auch der Fall, da der vom EDM generierte Schlüssel Probleme beim Duplizieren von Daten verursachte. Daher musste ich eine nullfähige Spalte als nicht nullfähig definieren, um zu erzwingen, dass der zusammengesetzte Schlüssel im EDM diese Spalte enthält.
quelle
Context.Entity.ToList()
doppelte Datensätze ausführen, die von EF generierte SQL-Abfrage jedoch direkt ausführen (mit LINQPad erhalten), erfolgt keine doppelte Datensätze. Scheint ein Problem zu sein, die Datenbankeinträge den zurückgegebenen Entitätsobjekten (POCO) zuzuordnen, da die PK unter Verwendung der erläuterten Logik (nicht nullbare Spalten) abgeleitet wird.Es scheint ein bekanntes Problem mit EdmGen zu sein: http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/12aaac4d-2be8-44f3-9448-d7c659585945/
quelle
Um eine Ansicht zu erhalten, musste ich nur eine Primärschlüsselspalte anzeigen. Ich habe eine zweite Ansicht erstellt, die auf die erste zeigt, und NULLIF verwendet, um die Typen auf Null zu setzen. Dies hat für mich funktioniert, um die EF glauben zu lassen, dass nur ein einziger Primärschlüssel in der Ansicht enthalten ist.
Ich bin mir nicht sicher, ob dies Ihnen helfen wird, da ich nicht glaube, dass die EF eine Entität ohne Primärschlüssel akzeptiert.
quelle
Wenn Sie sich nicht mit dem Primärschlüssel anlegen möchten, empfehle ich:
ROW_NUMBER
in Ihre Auswahlquelle
Aufgrund der oben genannten Probleme bevorzuge ich Tabellenwertfunktionen.
Wenn Sie dies haben:
Erstellen Sie dies:
Dann importieren Sie einfach die Funktion und nicht die Ansicht.
quelle