2017-09-18 1 views
0

Je suis nouveau sur ASP.NET MVC et Entity Framework. Je crée un projet de concessionnaire automobile en utilisant l'approche Code First. J'ai 3 tables (classes):
Code EF ASP.NET MVC 5 Premier chargement des données de 3 tables connexes

voiture, pour stocker des données de voiture
CarBrand, pour stocker des marques comme Ford, Fiat, BMW ...
CarModel, pour le stockage de modèles Fiesta, Panda, 318 ..

La classe Car a une classe FK à CarModel. La classe CarModel a un FK pour CarBrand.

voici mes classes:

public class Car 
{ 
    public int Id { get; set; } 
    public string Description{ get; set; } 
    public decimal Price{ get; set; } 

    public CarModel CarModel { get; set; } 
    public int CarModelId { get; set; } 

    ..... (more properties) 
} 

public class CarBrand 
{ 
    public int CarBrandId { get; set; } 
    public string Description{ get; set; } 
} 

public class CarModel 
{ 
    public int CarModelId { get; set; } 
    public string Description{ get; set; } 

    public int CarBrandId { get; set; } 
    public CarBrand CarBrand { get; set; } 
} 

Je veux charger des données de tous les 3 tables. Je suis en mesure de charger des données à partir de 2 tables avec le code suivant dans le contrôleur:

var cars = _context.Cars.Include(c => c.CarModel).ToList(); 

Comment charger les données de CarBrand aussi? Ai-je configuré les classes avec les propriétés de navigation correctement?

Une fois que je charge les données, je suppose que j'ai besoin d'un ViewModel pour stocker et envoyer les données à la vue fortement typée, non?

Au moment de mon ViewModel est:

public class CarsModelsViewModel 
{ 
    public CarModel CarModel { get; set; } 
    public CarBrand CarBrand { get; set; } 
    public List<Car> Cars { get; set; } 
} 

Répondre

0

Pour inclure plusieurs niveaux, il est plus facile d'utiliser la chaîne surcharge PARAM Include:

.Include("CarModel.CarBrand") 

Cependant, vous pouvez obtenir le même résultat, en sélectionnant simplement le niveau supplémentaire:

.Include(m => m.CarModel.Select(b => b.CarBrand)) 

La taxe commence à être un peu méchante de cette façon, cependant, en particulier avec plus de deux niveaux d'entités connexes.

Cela dit, personnellement, je changerais un peu la conception de vos entités. La relation entre le modèle et la marque sert un objectif différent de la relation entre une voiture et une marque. À mon avis, il est plus logique pour une voiture d'avoir une clé étrangère pour une marque.

public class Car 
{ 
    public int Id { get; set; } 
    public string Description{ get; set; } 
    public decimal Price{ get; set; } 

    public CarBrand CarBrand { get; set; } 
    public int CarBrandId { get; set; } 

    public CarModel CarModel { get; set; } 
    public int CarModelId { get; set; } 

    ..... (more properties) 
} 

Ensuite, il vous suffit:

Include(m => m.CarBrand).Include(m => m.CarModel) 

Cela a aussi l'avantage que vous pouvez ajouter une propriété de navigation collection CarBrand afin d'obtenir toutes les voitures liées à cette marque, sans avoir à traverser toutes les les relations CarModel. En d'autres termes, alors qu'auparavant vous auriez à faire quelque chose comme:

var cars = brand.Models.SelectMany(m => m.Cars); 

Vous pouvez simplement faire quelque chose comme:

var cars = brand.Cars; 
+0

Merci pour la réponse Chris, les travaux de chargement de données! Maintenant, je suis en train d'implémenter votre suggestion concernant l'ajout d'une clé étrangère à la classe Car. J'obtiens l'erreur suivante lors de la création d'une nouvelle migration avec la classe mise à jour: Présentation de la contrainte FOREIGN KEY 'FK_dbo.Cars_dbo.CarModels_CarModelId 'sur la table' Cars 'peut provoquer des cycles ou plusieurs chemins en cascade. Spécifiez ON DELETE NO ACTION ou ON UPDATE NO ACTION ou modifiez d'autres contraintes FOREIGN KEY. –