2012-06-26 1 views
0

J'utilise un modèle produit avec Devart Entity Developer (fichier .edml, que je comprends est principalement similaire à .edmx) pour générer des classes Entity dont les relations sont initialisées dans une classe DbContext. Le schéma de base de données ne spécifie pas PK pour View1 et toutes les colonnes sont nullables. Mais la génération de code suppose que pour les vues dépourvues de clé primaire, toutes les colonnes sont la clé. À savoir, le .ssdl a toutes les colonnes sous l'élément clé et le DbContext a .IsRequired() spécifié sur tout, comme ceci:Représenter la vue sans clé dans Entity Framework

Extrait SSDL:

... 
<EntityType Name="View1"> 
    <Key> 
    <PropertyRef Name="FirstCol" /> 
    <PropertyRef Name="Col2" /> 
    <PropertyRef Name="LastCol" /> 
    </Key> 
    <Property Name="FirstCol" Type="VARCHAR2" Nullable="false" MaxLength="4000" /> 
    <Property Name="Col2" Type="VARCHAR2" Nullable="false" MaxLength="120" /> 
    <Property Name="LastCol" Type="VARCHAR2" Nullable="false" MaxLength="20" /> 
</EntityType> 
.... 

De DbContext:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{  
    #region View1 
    modelBuilder.Entity<View1>() 
    .HasKey(p => new { p.FirstCol, p.Col2, p.LastCol}) 
     .ToTable("View1", "Owner"); 
     // Properties: 
     modelBuilder.Entity<View1>() 
      .Property(p => p.FirstCol) 
      .HasColumnName("FirstCol") 
      .IsRequired() 
      .HasMaxLength(4000) 
      .HasColumnType("VARCHAR2"); 
     modelBuilder.Entity<View1>() 
      .Property(p => p.Col2) 
      .HasColumnName("Col2") 
      .IsRequired() 
      .HasMaxLength(120) 
      .HasColumnType("VARCHAR2"); 
     modelBuilder.Entity<View1>() 
      .Property(p => p.LastCol) 
      .IsRequired() 
      .HasMaxLength(20) 
      .HasColumnType("VARCHAR2"); 

Cela provoque une exception NullReferenceException lorsque l'interrogation renvoie une ligne avec l'une des colonnes PK ayant une valeur null.

Existe-t-il un moyen de représenter une vue dans EF sans spécifier de clés ou modifier le schéma de base de données? J'ai trouvé ceci: http://elegantcode.com/2012/03/15/querying-entityframework-views-without-a-key/

Est-ce la solution préférée? Je suppose que je pourrais aussi utiliser DefiningQuery, mais cela semble dupliquer le sql qui a été utilisé pour générer la vue?

Répondre

1

Vous devez effectuer les étapes suivantes:

  1. Pour toutes les colonnes de l'entité définissez la propriété Entité clé False dans les parties conceptuelles et de stockage du modèle.
  2. Ajoutez la propriété Id du type de chaîne à l'entité dans la partie conceptuelle du modèle et définissez la valeur de la clé d'entité sur True.
  3. Si la synchronisation des composants conceptuels et de stockage est activée (Boîte de dialogue Paramètres du modèle-> Synchronisation-> Mappage), la colonne Id sera automatiquement ajoutée à l'entité existante dans la partie de stockage. Vous devez définir Type = ROWID et Name = ROWID pour cette colonne. La cartographie sera personnalisée automatiquement. Si la synchronisation est désactivée, ajoutez la colonne ROWID à l'entité correspondante dans la partie de stockage et définissez-la sur Type = ROWID. Après cela, appelez le menu contextuel de la classe, sélectionnez l'élément Détails de mappage et dans la boîte de dialogue affichée, spécifiez le mappage de colonne valide.
  4. Pour les autres propriétés de la classe définie sur Nullable to True.

article Edité 3: nom de la colonne de l'entité dans la partie de stockage doit être rowid

+0

J'ai essayé et je reçois une erreur 'ORA-00904: « Extent1 » « Id »:. Identifiant invalide 'lorsque vous essayez d'interroger Linq sur les entités. Je vois que le sql généré par l'EF essaie de rechercher une colonne d'identifiant qui n'existe pas. Avez-vous suggéré de mettre à jour la vue de la base de données pour avoir un rowid? Ma question était de faire des changements sans altérer la base de données. – ossek

+1

Nous avons modifié notre réponse.S'il vous plaît noter que l'algorithme décrit fonctionne pour les vues créées sans utiliser des constructions comme UNION, GROUP BY etc. – Devart

+0

Merci pour vos commentaires et éditer. Malheureusement, la définition de la vue implique UNIONs. Y aurait-il une autre pseudocolonne ou convention que je pourrais utiliser à la place de ROWID? – ossek

0

Vous pouvez définir la clé primaire (étant donné que vous pouvez garantir l'affichage des données uniques de la clé que vous définissez) par rapport à une vue oracle du fournisseur devart EF en ouvrant edml dans le concepteur et en définissant manuellement la clé primaire sur l'entité. ALORS (c'est l'astuce qui rend ce travail) aller à la fenêtre de l'explorateur de modèle et faire les mêmes changements à la partie de magasin du modèle. En règle générale, si vous faites simplement glisser une vue sur la surface de conception du modèle EF, devart tentera de déduire une clé primaire d'une vue qui n'a pas été définie. Encore une fois, il est essentiel que votre vue renvoie des données uniques pour la clé que vous définissez.

Questions connexes