Oracle
 sql >> Base de données >  >> RDS >> Oracle

Utiliser une vue sans clé primaire avec Entity

Est-il possible d'ajouter une vue au modèle Entity sans identifiant unique ?

Si sans clé primaire, non. Cela entraînera ce type d'erreur :

Une ou plusieurs erreurs de validation ont été détectées lors de la génération du modèle :

System.Data.Edm.EdmEntityType ::EntityType 'SalesOnEachCountry' n'a pas de clé définie. Définissez la clé pour cet EntityType.System.Data.Edm.EdmEntitySet :EntityType :EntitySetSalesOnEachCountryList est basé sur le type SalesOnEachCountry qui n'a défini aucune clé.

Si sans identifiant unique, oui, bien qu'il ait une sortie non souhaitable. Les enregistrements avec le même identifiant feraient référence au même objet, c'est ce qu'on appelle le modèle de carte d'identité

Un exemple, même si votre vue produit ces deux lignes :

Country     Year TotalSales
Philippines 2010 20.000000
Philippines 2011 40.000000

Si vous mappez simplement la clé primaire sur le champ Pays uniquement, par ex.

public class SalesOnEachCountry
{        
    [Key]
    public int CountryId { get; set; }
    public string CountryName { get; set; }        
    public int OrYear { get; set; }
    public long SalesCount { get; set; }
    public decimal TotalSales { get; set; }
}

, même votre vue produit les deux lignes ci-dessus sur votre éditeur de requête Oracle, Entity Framework produit cette sortie incorrecte :

Country     Year TotalSales
Philippines 2010 20.000000
Philippines 2010 20.000000

Entity Framework considérera que la deuxième ligne est le même objet que la première ligne.

Pour garantir l'unicité, vous devez identifier les colonnes qui rendent chaque ligne unique. Dans l'exemple ci-dessus, Year doit être inclus afin que la clé primaire soit unique. c'est-à-dire

public class SalesOnEachCountry
{        
    [Key, Column(Order=0)] public int CountryId { get; set; }
    public string CountryName { get; set; }
    [Key, Column(Order=1)] public int OrYear { get; set; }

    public long SalesCount { get; set; }      
    public decimal TotalSales { get; set; }
}

En rendant votre clé primaire similaire aux attributs ci-dessus, Entity Framework peut mapper correctement la ligne de chaque vue à ses propres objets. Par conséquent, Entity Framework peut désormais afficher exactement les mêmes lignes que votre vue.

Country     Year TotalSales
Philippines 2010 20.000000
Philippines 2011 40.000000

Tous les détails ici :http://www.ienablemuch.com/2011/06/mapping-class-to-database-view-with.html

Ensuite, en ce qui concerne vos vues qui n'ont pas de colonnes pour rendre une ligne unique, le moyen le plus simple de garantir qu'Entity Framework peut mapper chacune des lignes de votre vue à leurs propres objets est de créer une colonne distincte pour la clé primaire , un bon candidat consiste simplement à créer une colonne de numéro de ligne sur chaque ligne. ex.

create view RowNumberedView as

select 
    row_number() over(order by <columns of your view sorting>) as RN
    , *
from your_existing_view

Attribuez ensuite la [Key] attribut sur la propriété RN de votre class RowNumberedView