0

Je crée un site en utilisant EF database-first avec ASP.NET MVC (je suis tout ce tutoriel: https://www.asp.net/mvc/overview/getting-started/database-first-development/creating-the-web-application) et tout fonctionne bien.Base de données C# Entity Framework D'abord - utiliser seulement quelques champs

Le problème est que dans la vue d'index (la liste d'enregistrements) je veux supprimer l'un des champs de l'entité. Je ne veux pas seulement que cela soit caché dans les vues, mais toutes ensemble supprimées (le problème est qu'il contient un très gros morceau de données, ce qui rend le chargement de la liste très lent).

Dans la vue "Modifier", je souhaite afficher et utiliser tous les champs.

Si je supprime un champ de l'entité, je reçois cette erreur:

The entity type XXX is not part of the model for the current context.

sur

return View(db.XXX.ToList()); 

Que puis-je faire?

+1

Si vous souhaitez supprimer un champ d'une entité, il suffit de supprimer ce champ de l'entité, et non l'entité entière du modèle. – Antrim

+0

Ajoutez l'attribut Ignorer au champ et EF ne l'utilisera pas dans les requêtes ou le peuplera avec des données. –

+0

Ne répond pas à votre question et n'est probablement pas une aide du tout, mais pourquoi faites-vous db en premier si vous voulez des modèles personnalisés? Ceci est si facilement réalisable dans une première approche de code. – Omeed

Répondre

1

Il y a plusieurs façons de procéder. Le problème, à portée de main, est le .ToList(). Si vous ne faites que db.XXX, alors vous obtiendrez un Enumerable, qui, jusqu'à ce qu'il soit énuméré, est juste un ensemble d'instructions pour saisir des données de la base de données. Une fois que vous appelez .ToList(), il va effectivement récupérer les données de la base de données, ce qui est l'étape qui prend si longtemps. À mon avis, la meilleure chose à faire est de définir un ViewModel qui contient tous les champs à l'exception de celui avec la grande quantité de données.

public class ViewModel 
{ 
    public ViewModel(){} 
    public int Id {get;set;} 
    public string OtherData {get;set;} 
} 

Déplacer le db.XXX en dehors de la fonction Afficher en sorte:

var initialDBObject = db.XXX; 

De là, vous pouvez prendre votre Enumerable (qui est toujours juste un ensemble d'instructions pour accéder aux données de votre DB) et sélectionnez-le dans votre objet ViewModel comme ceci:

var viewModelObject = initialDBObject.Select(x=> new ViewModel 
    { 
     Id = x.Id; 
     OtherData = x.OtherData; 
     //do not add the large column of data to the ViewModel 
    }); 

ce qui se passe ici (avant d'appeler ToList()) est que vous modifiez la requête LINQ génère derrière les scènes pour récupérer les données de la table XXX (si vous mettez un point d'arrêt sur cette ligne et survolez initialDBObject vous verrez le SQL qui est généré). Au lieu de saisir simplement les données de la table XXX, la requête récupère les données et les insère dans un objet ViewModel (au lieu de l'objet XXX, tel que défini dans votre fichier .edmx) une fois que vous avez appelé ToList().

Vous pouvez également

.Select(x=> new 
{ 
    Id, 
    OtherData 
}); 

et de créer un objet anonyme, mais obtenir un objet anonyme à travailler dans une vue est un peu compliqué.

Ensuite, vous devez mettre à jour la page de vue d'index pour utiliser le ViewModel au lieu de l'objet DB original et vous pouvez le transmettre comme:

View(viewModelObject.ToList()); 

Nom la chose ViewModel en plus ViewModel, cependant. Comme [DB Table Name] ViewModel ou quelque chose de similaire.

Si vous avez beaucoup de lignes dans la base de données, il faudra encore beaucoup de temps pour charger toutes les données, auquel cas vous devrez regarder dans la pagination.

Il n'y a pas de problème avec ToList(), à lui seul, le problème d'origine a été provoqué par l'appel à ToList() parce que c'est à ce point du code que le programme va à la base de données. requête générée pour récupérer les données. Si vous essayez de ToList() une table entière de données, ou comme dans votre cas, avoir une colonne avec un gros morceau de données, cela peut prendre un certain temps ou vous pouvez manquer de mémoire. En ce qui concerne les 15 colonnes que vous devez inclure dans le .Select(), oui, c'est ennuyeux. Malheureusement, vous ne pouvez pas utiliser un constructeur dans une instruction linq, vous devez donc remplir chaque colonne. Une autre alternative à la définition d'un ViewModel, qui peut être un peu plus facile, est d'ouvrir la surface de conception .edmx, de cliquer avec le bouton droit sur l'arrière-plan et d'ajouter Nouveau-> Entité. Vous pouvez utiliser la table XXX comme base, lui donner un nom différent, comme XXXViewModel ou autre, puis supprimer la colonne contenant la grande quantité de données. Ensuite, vous avez juste besoin de faire db.XXXViewModel.ToList().

+0

Merci U RIanGillis! Deux questions: 1. Je ne comprends pas vraiment cette ligne: initialDBObject.select (x => nouveau ViewModel.il y a un nouveau modèle de vue dans le select?) 2. J'ai environ 15 champs, il devrait y avoir tous dans le select, semble problématique. .. – webmobileDev

+0

Aussi, je ne comprends pas pourquoi ToList est le problème? – webmobileDev

+0

J'ai mis à jour la réponse à vos questions – RIanGillis