136 votes

Entity Framework et SQL Server View

Pour plusieurs raisons que je n'ai pas la liberté de parler, nous sommes à la définition d'une vue sur notre Sql Server 2005 de la base de données comme suit:

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

L'idée est que le Cadre de l'Entité permettra de créer une entité basée sur cette requête, ce qu'il fait, mais il génère un message d'erreur qui indique les éléments suivants:

Avertissement 6002: La table/vue 'Keystone_Local.dbo.MeterProvingStatisticsPoint " n'a pas de clé primaire. La clé a été déduite et la définition a été créé comme un tableau en lecture seule/vue.

Et il décide que le CompletedDateTime champ sera cette entité de la clé primaire.

Nous sommes à l'aide de EdmGen pour générer le modèle. Est-il un moyen de ne pas avoir l'entité cadre d'inclure n'importe quel champ de ce point de vue comme une clé primaire?

247voto

Tillito Points 2625

Nous avons eu le même problème et il s’agit de la solution :

Pour forcer l’entity framework pour utiliser une colonne comme clé primaire, utiliser ISNULL.

Pour forcer l’entity framework ne pas pour utiliser une colonne comme clé primaire, utilisez NULLIF.

Un moyen facile d’appliquer ce consiste à encapsuler l’instruction select de la vue à une autre sélection.

Exemple :

68voto

Casey Points 161

J'ai été en mesure de résoudre ce à l'aide de la designer.

  1. Ouvrez l'explorateur de modèles.
  2. Trouver les afficher dans le diagramme.
  3. Clic droit sur la clé primaire, et assurez-vous que "Personne Clé" est cochée.
  4. Multi-sélection de tous les non-clés primaires. Utiliser les touches Ctrl ou Shift.
  5. Dans la fenêtre Propriétés (appuyez sur la touche F4 si nécessaire pour voir), changez l' "Personne Clé" drop-down pour de Faux.
  6. Enregistrer les modifications.
  7. Fermez Visual Studio et ouvrez-la à nouveau. Je suis à l'aide de Visual Studio 2013 avec EF 6 et j'ai dû le faire pour obtenir les mises en garde de s'en aller.

Je n'ai pas eu à changer mon point de vue, l'utilisation de la ISNULL, NULLIF, ou FUSIONNER des solutions de contournement. Si vous mettez à jour votre modèle à partir de la base de données, les mises en garde apparaîtra de nouveau, mais d'aller loin si vous fermez et ré-ouvrez VS. Les modifications que vous avez apportées dans le concepteur seront conservées et ne sont pas affectés par l'actualisation.

46voto

Val Bakhtin Points 984

D'accord avec @Tillito, cependant, dans la plupart des cas, faute optimiseur SQL et il ne sera pas du droit d'utilisation des indices.

C'est peut-être évident pour quelqu'un, mais j'ai brûlé des heures à résoudre des problèmes de performances à l'aide de Tillito solution. Disons que vous avez de la table:

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

et votre point de vue est quelque chose comme ceci

 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

Optimiseur Sql de ne pas utiliser d'index ix_customer et il va effectuer une analyse de table sur le premier indice, mais si, au lieu de:

Group by CustomerId

vous utilisez

Group by IsNull(CustomerId, -1)

il va faire de MS SQL (au moins 2008) comprend des index droit dans le régime.

Si

9voto

SpazDude Points 689

Cette méthode fonctionne bien pour moi. J'utilise la fonction ISNULL() pour le champ de clé primaire, et se rejoignent() si le terrain ne doit pas être la clé primaire, mais devrait également avoir un non nullable valeur. Cet exemple rendements champ ID avec un pas les valeurs null clé primaire. Les autres champs ne sont pas des touches, et ont (Aucun) que de leur attribut Nullable.

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

si vraiment vous n'avez pas de clé primaire, vous pouvez usurper l'un par l'aide de la fonction ROW_NUMBER de générer un pseudo-clé qui est ignoré par votre code. Par exemple:

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

4voto

codified Points 462

L'Entité courante Cadre EDM générateur va créer une clé composite de tous les non nullable champs de votre point de vue. Afin d'en prendre le contrôle, vous aurez besoin de modifier la vue et de la table sous-jacente de colonnes les colonnes de prendre la valeur null lorsque vous ne souhaitez pas faire partie de la clé primaire. L'inverse est également vrai, comme je l'ai rencontrée, l'EDM a généré la clé était à l'origine des données-problèmes de duplication, j'ai donc dû définir une colonne nullable non nullable à la force de la clé composite dans la GED pour inclure cette colonne.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X