Mapper deux entités différentes à la même table?

J'ai une table dans ma base de données avec beaucoup de champs. la Plupart du temps j'ai besoin de tous les champs. Il y a un scénario, cependant, où je n'ai besoin que de quelques champs, et je charge une tonne de lignes.

Ce que je voudrais faire est d'ajouter manuellement une entité, puis de la mapper simplement à la table d'origine, mais de supprimer les colonnes dont je n'ai pas besoin. J'ai tout mis en place, mais j'ai l'erreur plutôt explicite de:

Problème dans le mappage des fragments ...EntitySets "FmvHistoryTrimmed" et 'FMVHistories' sont tous deux mappés à tableau "FMVHistory". Leurs clés primaires peuvent entrer en collision.

Y a-t-il un autre moyen que je devrais faire? Encore une fois, la plupart du temps Toutes les colonnes sont utilisées, donc je ne veux pas réduire l'entité d'origine et mettre les champs "supplémentaires" dans un type complexe.

35
demandé sur Adam Rackis 2011-02-23 19:14:41

2 réponses

Vous ne pouvez pas mapper deux entités régulières dans la même table. Vous avez plusieurs choix:

  1. Utilisez le fractionnement de table.
  2. Utiliser une requête personnalisée avec projection vers un type non entité (comme @ Alucci proposé)
  3. Utiliser QueryView
  4. utiliser la vue de base de données ou directement DefiningQuery

Tableau fractionnement

Le fractionnement de Table vous permet de mapper une table en deux entités dans une relation 1:1. La première entité ne contiendra que PK et sous-ensemble de champs que vous besoin de toujours. La deuxième entité contiendra tous les autres champs et PK. Les deux entités contiendront la propriété de navigation l'une à l'autre. Maintenant, si vous n'avez besoin que d'un sous-ensemble de champs, vous interrogerez la première entité. Si vous avez besoin de tous les champs, vous interrogerez la première entité et inclurez la propriété navifation à la deuxième entité. Vous pouvez également charger paresseux deuxième entité si vous en avez besoin.

QueryView

QueryView est une requête ESQL définie directement dans votre mappage (MSL) et elle est mappée à new type d'entité en lecture seule. Vous pouvez utiliser QueryView pour définir la projection de votre entité complète en sous-entité. QueryView doit être défini manuellement dans EDMX (il n'est pas disponible dans designer). Comme je le sais, QueryView n'est pas disponible en premier dans le Code, mais il est en fait le même que la projection personnalisée vers un type non entité.

DefiningQuery

DefiningQuery est une requête personnalisée définie directement dans votre modèle de stockage (SSDL). DefiningQuery est généralement utilisé lors du mappage vers les vues de base de données mais vous pouvez l'utiliser pour N'importe quelle sélection SQL personnalisée. Vous mapperez le résultat de la requête au type d'entité readonly. DefiningQuery doit être défini manuellement dans EDMX (il n'est pas disponible dans designer). Il n'est pas non plus directement disponible dans le Code en premier, mais c'est en fait la même chose que d'appeler SqlQuery sur DbDatabase. Le problème avec DefiningQuery est qu'une fois que vous l'avez défini manuellement dans SSDL, vous ne pouvez pas utiliser Update model from database car cette opération remplace SSDL complet et supprime la définition de votre requête.

32
répondu Ladislav Mrnka 2011-02-23 17:31:19

Je créerais une vue sur la base de données contenant uniquement les données dont vous avez besoin et ajouterais la vue à votre modèle de données d'entité.

Si vous ne souhaitez pas modifier la base de données, vous pouvez créer une instruction Linq to entities ou ESQL projetant vers une classe POCO avec uniquement les informations dont vous avez besoin.

public IQueryable<SimpleObject> GetView(DBContext context)
{
    return  (from obj in context.ComplexObjects
            select new SimpleObject() { Property1 = obj.Property1,
                                        Property1 = obj.Property2
                                      }); 
}
8
répondu Aducci 2011-02-23 16:41:33