3 Stimmen

MVVM-Modell mit Entity Framework

Ich habe einen Prototypen mit WPF + MVVM + PRISM + ENTITY FRAMEWORK.

Das Problem ist, dass ich sehr verwirrt bin, ob ich die ENTITY FRAMEWORK-Entitäten als Modell des MVVM-Musters verwenden soll. Ich habe eine Business-Logik-Ebene, und ich hatte Probleme bei der Verwendung von Mappern in dieser Ebene, weil ich mit der Konvertierung sehr unzufrieden bin (Map-Problem).

Was kann ich tun, um den Code zu vereinfachen, ein echtes Modell zu verwenden und nicht das Entitätsobjekt (für mich ist die Verwendung der Entität als Modell auf der Benutzeroberfläche falsch), mit dem MVVM-Muster im Kopf... und bereit für zukünftige Änderungen zu bleiben, es wird 200+ Entitäten in der endgültigen Version geben...

Das sind meine Schichten...(Bitte vergessen Sie das Mapping, da ich es entfernt habe, indem ich die EF-Entitäten auf das ViewModel gesetzt habe, aber das Bild repräsentiert die richtigen Schichten)

Ich verwende auch kein Repository, da ich es am Ende mit Änderungen nur in der BLL hinzufügen kann.

Meine Schichten

VIEW MODEL: Mein aktueller Prototyp führt ein Getall aus, fügt es in ein Raster ein und beim Ändern der Auswahl im Raster wird das ausgewählte Element in das Textfeld eingefügt, und die Schaltfläche "Speichern" aktualisiert diese Änderungen in der Datenbank.

public class CadastroClienteViewModel : BindableBase, ICadastroClienteViewModel
{
    private readonly IClienteBLL _clienteService;

    #region Modell
    //public Cliente ObCliente { get; private set; }

    public int ClienteID
    {
        get { return ((Cliente)cliItems.CurrentItem).ClienteID; }
        set
        {
            ((Cliente)cliItems.CurrentItem).ClienteID = value;
            OnPropertyChanged("ClienteID");
        }
    }

    public string Nome
    {
        get { return ((Cliente)cliItems.CurrentItem).Nome; }
        set
        {
            ((Cliente)cliItems.CurrentItem).Nome = value;
            OnPropertyChanged("Nome");
        }
    }

    #endregion

    public CadastroClienteViewModel(IClienteBLL ServiceCliente)
    {
        //ObCliente = new Cliente();
        _clienteService = ServiceCliente;

        this.SaveCommand = new DelegateCommand(ExecuteMethodSave);
        this.RefreshCommand = new DelegateCommand(ExecuteMethodRefresh, CanExecuteMethodRefresh);
        RefreshCommand.Execute(null);
    }

    private void ExecuteMethodSave()
    {
        _clienteService.ClienteBLL_Update(((Cliente)cliItems.CurrentItem));

        RefreshCommand.Execute(null);
    }

    private bool CanExecuteMethodRefresh()
    {
        return true;
    }

    private void ExecuteMethodRefresh()
    {
        var personViewModels = _clienteService.ClienteBLL_GetAll();

        //cliente = new ObservableCollection(personViewModels);

        cliItems = new ListCollectionView(personViewModels.ToList());
        cliItems.CurrentChanged += CliItemsOnCurrentChanged;

        //OnPropertyChanged("cliente");
        OnPropertyChanged("cliItems");
    }

    private void CliItemsOnCurrentChanged(object sender, EventArgs eventArgs)
    {
        //OnPropertyChanged("ObCliente");
    }

    public ICommand SaveCommand { get; private set; }
    public ICommand RefreshCommand { get; private set; }

    //public ObservableCollection cliente { get; private set; }
    public ICollectionView cliItems { get; private set; }
}

MODELL (Ich verwende es nicht... aber ich würde es gerne):

public class MCliente
{
    public int ClienteID { get; set; }
    public string Nome { get; set; }
}

EF Entität:

namespace Sistema.DataEntities.Models
{
public class Cliente
{
    public Cliente()
    {
    }

    public int ClienteID { get; set; }

    public string Nome { get; set; }
}

BLL:

public class ClienteBLL : IClienteBLL
{
    readonly ISistemaContext _context;
    public ClienteBLL(ISistemaContext context)
    {
        _context = context;
    }

    public IEnumerable ClienteBLL_GetAll()
    {
        return _context.Cliente.AsEnumerable();
    }

    public Cliente ClienteBLL_GetByID(int id)
    {
        return _context.Cliente.Find(id);
    }

    public bool ClienteBLL_Adicionar(Cliente Obcliente)
    {
        _context.Cliente.Add(Obcliente);
        return _context.SaveChanges() > 0;
    }

    public bool ClienteBLL_Update(Cliente Obcliente)
    {
        _context.Cliente.Attach(Obcliente);
        _context.Entry(Obcliente).State = EntityState.Modified;
        return _context.SaveChanges() > 0;
    }

    public bool ClienteBLL_Delete(int id)
    {
        var clubMember = _context.Cliente.Find(id);
        _context.Cliente.Remove(clubMember);
        return _context.SaveChanges() > 0;
    }

4voto

ken2k Punkte 46913

Ich füge dies als Antwort hinzu (nicht als Kommentar), auch wenn es keine endgültige Antwort auf Ihre Frage ist (weil sie auf Meinungen basiert), aber es passt nicht als Kommentar. Das ist nur das, was ich für eine WPF-Anwendung machen würde, die eine Datenbank benötigt.

Ich würde die Idee, Ihre WPF-Anwendung direkt mit Ihrer Datenbank zu verbinden, vollständig verwerfen. Ich würde eine 3-Schichten-Architektur aufbauen, d.h. ich würde einen zustandslosen Webservice erstellen, der auf der Serverseite alle Aufgaben erledigt.

Daher hätten Sie:

  • die Datenbank
  • den Webservice (mit WCF), der mit der Datenbank verbunden ist und alle Datenvorgänge für Sie durchführt (ich würde ihn sogar für die Geschäftsvorgänge verantwortlich machen)
  • die WPF-Anwendung, die mit dem Webservice verbunden ist:
    • Die Ansichtsschicht ist Ihr XAML + Ihr Code-Behind
    • Die ViewModel-Schicht sind Ihre ViewModels (außerhalb des Umfangs Ihrer Frage, aber wenn Sie Fragen zu dieser Schicht haben, können Sie diese gerne stellen). Die ViewModels rufen den Webservice asynchron auf
    • Das Modell ist der Client WCF-Proxy

Einige Vorteile dieses Ansatzes:

  • Je nach Hardware-/Netzwerkarchitektur könnte es ein enormer Leistungsvorteil sein, nur EINEN Aufruf an den Server zu tätigen, anstatt N Aufrufe (unter der Annahme, dass die Latenz zwischen der DB und dem Webservice (beide auf der "Serverseite") niedriger ist als die zwischen der WPF-Anwendung und der Datenbank)
  • skalierbarer
  • alle Vorteile des zustandslosen Ansatzes: eine Entity Framework-Kontextinstanziierung pro Webservice-Anfrage, also viel einfacher, mit Konkurrenzproblemen umzugehen (für den Fall, dass Sie N WPF-Instanzen gleichzeitig ausführen)
  • einfacher zu warten (loser Koppelung zwischen den Schichten)
  • einfacher zu testen (vorausgesetzt, Sie erstellen tatsächlich Tests)
  • bessere Sicherheit (kein direkter Zugriff auf die Datenbank über das Netzwerk erforderlich)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X