2009-08-17 5 views
0

Ok, alors laissez-moi vous expliquer un peu ce que j'essaie de faire.Asp.Net MVC Entity Framework Parent-enfant avec des valeurs remplaçables

J'ai une table appelée WebsitePage qui contient toutes les pages de mon site avec quelques informations à leur sujet. Ensuite, j'ai une table client pour tous mes clients. Ensuite, j'ai une autre table appelée CustomerWebsitePage qui stocke les valeurs client pour certaines des colonnes de la table WebsitePage. Donc, en utilisant le framework d'entité, j'ai importé ces trois tables. Ce que je veux être capable de faire est de retourner une liste de WebsitePage fortement typée qui a des valeurs de CustomerWebsitePage s'il y a des valeurs pour cela. Ainsi, par exemple, un de mes clients a ajouté un CustomerWebsitePageName pour l'une de mes pages de site Web. Je souhaite renvoyer une liste de pages Web contenant le CustomerWebsitePageName au lieu du nom de la page Web dans ce cas. Mais le nom original de WebsitePage pour tout le reste puisqu'il n'a pas été substitué.

Le pointeur ici est que ma table WebsitePage a une clé étrangère à elle-même pour une relation parent/enfant. Donc, je veux aussi retourner l'enfant WebsitePages en même temps. J'ai essayé d'utiliser une fonction d'importation pour obtenir ce que je voulais, mais bien sûr j'ai perdu les pages enfants.

J'ai essayé à peu près tout pour obtenir ce que je veux en utilisant le framework Entity et LINQ. Mais jusqu'à présent, presque tout ce que j'essaie finit avec une exception. Voici quelques-unes:

  • Le EntityCollection a déjà été initialisé
  • L'entité ou le type complexe 'MyEntityModel.WebsitePage' ne peut pas être construit dans une requête LINQ to entités.

J'ai une idée de la façon dont je peux contourner tout cela, et ce serait de reproduire le ParentPageID dans ma table de WebsitePage, mais cela semble vraiment violer beaucoup de principes et je vraiment tout simplement pas vouloir ajouter le mal de tête de maintenance liée à cela.

Quelqu'un at-il des idées pour accomplir ce genre de chose?

A simple DB diagram. http://images.tehone.com/screenshots/2009-08-17_013009.png

+0

On dirait que vous avez écrit une mauvaise requête LINQ to Entities, mais sans voir réellement cette requête et le code qui l'utilise, il est difficile d'être sûr. À première vue, votre mappage de base de données semble OK tel quel. –

Répondre

1

L'objet que vous avez besoin de revenir est un CustomerWebsitePage et non un WebsitePage. La raison en est que quel que soit l'objet que vous renvoyez doit savoir sur le client puisque la propriété en aura besoin pour déterminer quel champ (CustomerPage ou WebsitePage) à utiliser. Considérant cela, vous pouvez avoir une fonction CustomerWebsitePage.GetAllPagesForCustomer (client c) qui retournerait une énumération de pages. Cependant, pour obtenir la fonctionnalité que vous recherchez, vous devez implémenter certaines propriétés de lecture dans CustomerWebsitePage. Prenons l'exemple de Name. Ici serait la façon de mettre en œuvre dans CustomerWebsitePage:

public string Name 
{ 
    get{ if(String.IsNullOrEmpty(CustomerWebsitePageName)) 
      return WebsitePage.Name; 
     return CustomerWebsitePageName; } 
} 

Pour les pages enfants, vous pourriez avoir une propriété:

public IEnumerable<CustomerWebPage> Children 
{ 
    get 
    { 
     return WebsitePage.Children.Select(it => it.Customer.CustomerID == this.CustomerID);  } 
} 

Notez que cette configuration, vous ne pouviez pas exécuter des requêtes EF Linq sur ces nouveaux champs (car ils n'existent que dans les objets eux-mêmes, pas dans le mappage de la base de données). Vous pouvez pepper le code avec Load() si vous voulez charger de manière transparente tous les enfants, mais cela vous coûtera en performance.Pour faire en sorte que tous les enfants sont chargés, essayez la fonction de chargement suivant:

IEnumerable<CusomterWebPage> GetAllPagesForCustomer(Customer c) 
{ 
    return Context.CustomerWebPageSet.Include("WebsitePage").Where(it => it.Customer.CustomerID == c.CustomerID); 
} 
+0

Merci pour le conseil. J'ai décidé d'emprunter un itinéraire différent et de ne pas utiliser l'objet fortement typé pour effectuer le dépassement. Au lieu de cela, je ne fais que gérer moi-même la boucle de ces données. Je suppose que je pourrais dire que c'est une limitation de l'utilisation du framework Entity quand on essaye de faire ce genre d'héritage en remplaçant certaines valeurs. Qui sait, je peux même être capable d'utiliser le framework d'entité pour créer cet héritage. Mais pour l'instant au moins, je ne fais que le manipuler manuellement. Merci. – TehOne

Questions connexes