具有实体框架的MVVM模型

时间:2014-09-08 14:38:07

标签: c# wpf entity-framework mvvm

我有一个使用WPF + MVVM + PRISM + ENTITY FRAMEWORK的原型

如果我使用ENTITY FRAMEWORK实体作为MVVM模式的模型,问题就是非常混乱。我有一个业务逻辑层,我在这一层上使用mappers时遇到了问题,因为我对转换非常不满意(Map problem)。

我可以做些什么来简化代码,使用真正的模型而不是Entitie对象(对我来说使用Entitie作为模型在前端是不正确的),考虑到MVVM模式......并且保持良好对于未来的变化,最终版本将有200多个实体......

这是我的图层...(请忘记Mapping,因为我把它放在了ViewModel上,但是图像代表了正确的图层)

我也没有使用存储库,因为我只能在BLL上添加更改。

My layers

查看模型:     我当前的原型做了一个getall,把它放在一个网格上,并且在网格的selectchanged上我把选中的项放在文本框上,然后保存按钮更新这个更改到数据库。

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

    #region Model
    //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<Cliente>(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> cliente { get; private set; }
    public ICollectionView cliItems { get; private set; }
}

MODEL(我没有使用它...但我想):

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

EF Entitie:

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<Cliente> 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;
    }

2 个答案:

答案 0 :(得分:3)

我将此作为答案(不是评论)添加即使它不是您问题的最终答案(因为它基于意见),但它并不是适合作为评论。这就是我要为需要数据库的WPF应用程序做的事情。

我完全放弃了将WPF应用程序直接连接到数据库的想法。我将构建一个3层架构,即我将创建一个无状态的Web服务,它可以完成服务器端的所有工作。

所以你会:

  • 数据库
  • 连接到数据库的webservice(使用WCF),为您完成所有数据工作(我甚至会让它负责业务的东西)
  • 连接到webservice的WPF应用程序:
    • View层是您的XAML +您的代码隐藏
    • ViewModel图层就是您的ViewModel(超出了您的问题的范围,但随时可以询问您是否对该图层有任何疑问)。 ViewModels异步调用webservice
    • 模型是客户端WCF代理

这种方法的一些好处:

  • 取决于硬件/网络架构,只能对服务器进行一次调用而不是N次调用才能获得巨大的性能优势(假设数据库和Web服务之间存在延迟(两者都在& #34;服务器端&#34;)低于WPF应用程序和数据库之间的那个)
  • 更具可扩展性
  • 无状态方法的所有好处:每个Web服务请求一个实体框架上下文实例化,更容易处理并发问题(如果您同时运行N个WPF实例)
  • 更容易维护(层之间松散耦合)
  • 更容易测试(假设您实际构建测试)
  • 更好的安全性(无需通过网络公开对数据库的直接访问)

答案 1 :(得分:0)

更新:

5年后,互联网成为公司项目的最大关注点,所有新项目都是通过无状态API和SPA前端完成的。