Comme dans la question ci-dessus: Quelle est la meilleure façon de câbler le modèle de base de données Entity Framework (contexte) à viewModel dans MVVM (WPF)?
J'apprends le modèle MVVM dans WPF, beaucoup d'exemples montre comment implémenter le modèle pour viewModel, mais les modèles dans ces exemples ne sont que des classes simples, je veux utiliser MVVM avec le modèle de structure d'entité (approche de base). Quelle est la meilleure façon de câbler le modèle pour voir le modèle.
Merci pour les réponses.
//ctor of ViewModel
public ViewModel()
{
db = new PackageShipmentDBEntities(); // Entity Framework generated class
ListaZBazy = new ObservableCollection<Pack>(db.Packs.Where(w => w.IsSent == false));
}
Ceci est mon ctor habituel de ViewModel, pense qu'il y a une meilleure façon, je lisais sur le modèle de référentiel, je ne sais pas si je peux l'adapter à WPF MVVM
J'y ai beaucoup réfléchi et je n'ai pas trouvé de solution "parfaite". Le modèle de référentiel fonctionne à merveille pour les applications MVC où le contexte est de courte durée car il existe dans un contrôleur de courte durée, mais le problème se produit lorsque vous essayez d'appliquer cette même structure à une application wpf où le VM = peut persister pendant de longues périodes.
J'ai utilisé cette solution dans le passé, qui est beaucoup plus simple que la plupart des modèles de repo que j'ai vus et qui tentent d'abstraire les choses à un niveau extrême, résultant en des quantités de code presque illisibles difficiles à déboguer. Voici les étapes ...
Créez une classe de base "BaseRepository" pour agir comme "Unité de travail". IDisposable
vous permettra de l'utiliser dans une using(){}
et le partial
vous permettra de mettre en œuvre d'autres référentiels
public partial class MyEntityRepository : IDisposable
{
MyEntities context = new MyEntities();
public void Dispose()
{
context.Dispose();
}
}
Créez un autre fichier appelé "MyOtherRepository". créer la même classe partielle mais implémenter des méthodes basées sur ce que vous voulez que ce fichier contienne
public partial class MyEntityRepository
{
public void MyOtherMethodSave(EntityObject obj)
{
//work with context
...
context.SaveChanges();
}
}
Maintenant dans votre VM vous pouvez le faire ...
using(MyEntityRepository repo = new MyEntityRepository())
{
repo.MyOtherMethodSave(objectToSave);
}
Cela regroupe tous vos référentiels sous une seule classe afin que vous n'ayez pas à gérer un contexte séparé. Il vous permet de mieux gérer différents référentiels en regroupant les méthodes dans différents fichiers et aide à éviter la duplication de code. En plus de cela, vos contextes sont aussi éphémères qu'ils l'étaient sans utiliser ce modèle.
L'inconvénient est qu'avec des systèmes plus grands, vous pouvez avoir beaucoup de méthodes qui sont regroupées sous votre référentiel. Une solution dans ce cas serait d'implémenter certaines commandes communes de base comme "Rechercher" ou "Ajouter", et d'implémenter des commandes spécialisées dans leur référentiel respectif.
Opposé aux référentiels, ce que je n'aime pas. Je recommanderais d'utiliser le modèle de commande, comme recommandé par Ayende .
Autrement dit, pour chaque opération, vous créez une classe ThisOperationCommand
distincte. Dans cette classe, vous travaillerez avec un contexte EF normal. Vous pourriez même utiliser une classe de base EFCommand
qui fait de la plomberie pour vous.
Du côté de ViewModel, vous créez une instance de cette commande, la remplissez de paramètres (vous pouvez même passer toute l'instance de ViewModel si cela ne vous dérange pas un couplage étroit entre la commande et ViewModel), puis la transmettre à une sorte de Execute
, qui démarrera la commande, l'exécutera, la détruira et renverra ensuite ce que la commande a obtenu. Vous pouvez également lui faire retourner plusieurs valeurs si vous l'obtenez à partir de l'instance de la commande après l'exécution.
L'avantage est que vous n'avez pas besoin de dupliquer toute la couche d'accès aux données en tant que référentiel et que vous pouvez réutiliser et composer des commandes tant que vous créez une infrastructure simple pour la prendre en charge. Par exemple, exécuter des commandes à partir d'autres commandes.
Pour des scénarios simples, j'ai utilisé ce qui suit:
public class ViewModel : IDisposable {
private EntitiesContext _context = new EntitiesContext();
private SomeEntity _model;
public SomeEntity Model {
get { return _model; }
}
public View(int id) {
_model = _context.SomeEntity.Find(id);
}
private ICommand _saveCommand = new RelayCommand(() => _context.SaveChanges());
public ICommand SaveCommand {
get { return _saveCommand; }
}
public void Dispose() {
_context.Dispose();
}
}