Frage

Aus mehreren Gründen, die ich habe nicht die Freiheit, darüber zu sprechen, definieren wir einen Blick auf unserem 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 wird eine Entität erstellen auf der Grundlage diese Abfrage, die es funktioniert, aber es erzeugt sich mit einem Fehler, die folgenden Zustände an:

  

Achtung 6002: Die Tabelle / view ‚Keystone_Local.dbo.MeterProvingStatisticsPoint‘ keinen Primärschlüssel definiert. Der Schlüssel wurde geschlossen und die Definition wurde als Nur-Lese-Tabelle / View erstellt.

Und es entscheidet, dass das CompletedDateTime Feld diese Einheit Primärschlüssel sein wird.

Wir verwenden EdmGen das Modell zu erzeugen. Gibt es eine Möglichkeit nicht das Entity Framework zu haben, gehören alle Felder dieser Ansicht als Primärschlüssel?

War es hilfreich?

Lösung

Wir hatten das gleiche Problem, und das ist die Lösung:

Entity Framework zu zwingen, eine Spalte als Primärschlüssel zu verwenden, verwenden Sie ISNULL.

Entity Framework Um zu erzwingen, nicht eine Spalte als Primärschlüssel zu verwenden, verwenden Sie NULLIF.

Eine einfache Möglichkeit, dies zu beantragen ist die Select-Anweisung Ihrer Ansicht in einer anderen wählen zu wickeln.

Beispiel:

SELECT
  ISNULL(MyPrimaryID,-999) MyPrimaryID,
  NULLIF(AnotherProperty,'') AnotherProperty
  FROM ( ... ) AS temp

Andere Tipps

Ich konnte dies mit dem Designer lösen.

  1. Öffnen Sie den Modellbrowser.
  2. Finden Sie die Ansicht im Diagramm.
  3. Rechtsklick auf den Primärschlüssel, und stellen Sie sicher, "Entity Key" aktiviert ist.
  4. Multi-wählen Sie alle Nicht-Primärschlüssel. Mit Strg oder Shift-Taste.
  5. Sie im Eigenschaftenfenster (drücken Sie F4, wenn es zu sehen, erforderlich), ändern Sie die "Entity Key" drop-down auf False fest.
  6. Änderungen speichern.
  7. Schließen Sie Visual Studio und öffnen Sie es erneut. Ich bin mit Visual Studio 2013 mit EF 6 und ich hatte, dies zu tun, die Warnungen zu erhalten, gehen Sie weg.

Ich habe nicht meine Ansicht ändern, um die ISNULL, NULLIF oder COALESCE Abhilfen zu verwenden. Wenn Sie Ihr Modell aus der Datenbank aktualisieren, werden die Warnungen wieder erscheinen, werden aber weggehen, wenn Sie in der Nähe und wieder öffnen VS. Die Änderungen, die Sie in dem Designer gemacht werden beibehalten und nicht durch die Refresh beeinflusst werden.

Vereinbaren Sie mit @Tillito, aber in den meisten Fällen wird es SQL-Optimierungs beschmutzen und es wird nicht richtig Indizes verwenden.

Es kann jemand offensichtlich sein, aber ich verbrannt Stunden Performance-Probleme zu lösen mit Tillito Lösung. Lassen Sie uns sagen Sie die Tabelle haben:

 Create table OrderDetail
    (  
       Id int primary key,
       CustomerId int references Customer(Id),
       Amount decimal default(0)
    );
 Create index ix_customer on OrderDetail(CustomerId);

und Ihre Ansicht ist so etwas wie diese

 Create view CustomerView
    As
      Select 
          IsNull(CustomerId, -1) as CustomerId, -- forcing EF to use it as key
          Sum(Amount) as Amount
      From OrderDetail
      Group by CustomerId

SQL-Optimierer nicht Index ix_customer verwenden und es wird Tabelle Scan Primärindex durchführen, aber wenn statt:

Group by CustomerId

Sie verwenden

Group by IsNull(CustomerId, -1)

wird es MS SQL (mindestens 2008) richtig machen Index in Plan enthalten.

Wenn

Diese Methode funktioniert gut für mich. Ich benutze ISNULL () für das Primärschlüsselfeld und COALESCE (), wenn das Feld nicht der Primärschlüssel sein sollte, soll aber auch einen nicht-Nullable-Wert hat. Dieses Beispiel ergibt ID-Feld mit einem nicht-NULL festlegbare Primärschlüssel. Die anderen Felder sind keine Schlüssel, und haben (keine) als Nullable-Attribut.

SELECT      
ISNULL(P.ID, - 1) AS ID,  
COALESCE (P.PurchaseAgent, U.[User Nickname]) AS PurchaseAgent,  
COALESCE (P.PurchaseAuthority, 0) AS PurchaseAuthority,  
COALESCE (P.AgencyCode, '') AS AgencyCode,  
COALESCE (P.UserID, U.ID) AS UserID,  
COALESCE (P.AssignPOs, 'false') AS AssignPOs,  
COALESCE (P.AuthString, '') AS AuthString,  
COALESCE (P.AssignVendors, 'false') AS AssignVendors 
FROM Users AS U  
INNER JOIN Users AS AU ON U.Login = AU.UserName  
LEFT OUTER JOIN PurchaseAgents AS P ON U.ID = P.UserID

Wenn Sie wirklich nicht einen Primärschlüssel haben, können Sie eine fälschen durch ROW_NUMBER mit einem pseudo-Schlüssel zu generieren, die von Ihrem Code ignoriert. Zum Beispiel:

SELECT
ROW_NUMBER() OVER(ORDER BY A,B) AS Id,
A, B
FROM SOMETABLE

Der aktuelle Entity Framework EDM-Generator einen zusammengesetzten Schlüssel aus allen Nicht-Nullable-Feldern in der Ansicht erstellen. Um die Kontrolle über diese zu gewinnen, müssen Sie die Ansicht und die zugrunde liegenden Tabellenspalten ändern, um die Spalten Einstellung auf NULL-Werte zulässt, wenn Sie nicht wollen, dass sie Teil des Primärschlüssels sein. Das Gegenteil ist auch wahr, wie ich festgestellt, die EDM-generierten Schlüssel wurden Daten-Duplizierung Probleme verursacht, so hatte ich eine Spalte von -zulässige als Nicht-NULL-Werte zulassen definieren den Verbundschlüssel in der EDM zu zwingen, diese Spalte zu schließen.

Um eine Ansicht erreiche ich nur Show hatte ein Primärschlüsselspalte habe ich eine zweite Ansicht, die der ersten und verwendet NULLIF wies auf die Typen auf NULL festlegbare zu machen. Dieser arbeitete für mich die EF zu machen scheint, dass nur ein einziger Primärschlüssel in der Ansicht war.

Nicht sicher, ob dies wird Ihnen jedoch helfen, da ich nicht glaube, das EF wird eine Einheit mit keinen Primärschlüssel übernehmen.

ich auch empfehlen, wenn Sie mit nicht zu verwirren wollen, was der Primärschlüssel sein sollte ROW_NUMBER, um Ihre Auswahl zu übernehmen und sie als Primärschlüssel festgelegt und alle anderen Spalten / memebers als Nicht-Primär im Modell festgelegt.

Aufgrund der oben genannten Probleme, ziehe ich Wert Funktionen Tabelle.

Wenn Sie diese:

CREATE VIEW [dbo].[MyView] AS SELECT A, B FROM dbo.Something

erstellen folgt aus:

CREATE FUNCTION MyFunction() RETURNS TABLE AS RETURN (SELECT * FROM [dbo].[MyView])

Dann importieren Sie einfach die Funktion, anstatt die Ansicht.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top