【问题标题】:MVVM Model with Entity Framework带有实体框架的 MVVM 模型
【发布时间】:2014-09-08 14:38:06
【问题描述】:

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

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

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

那是我的层...(请忘记映射,因为我将 EF 实体放在 ViewModel 上,但图像代表正确的层)

我也没有使用存储库,因为我可以在最后添加它,只在 BLL 上进行更改。

查看模型: 我当前的原型做一个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 实体:

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

【问题讨论】:

  • 如果你没有额外的模型层,那么你就不必来回映射,如果你有,那么它到底能给你什么?
  • 实体框架更新问题...内部异常...stackoverflow.com/questions/25454801/…
  • 我真的不明白额外的模型层对此有何帮助。
  • 把 EF Entities 放到 ViewModel 上可以吗?这对我来说听起来很奇怪,这就是为什么......
  • 使用 EF 实体作为视图模型很好,因为实体都是 pocos。您可以将模型和业务层合并为一个,因为模型应该具有逻辑并编排业务逻辑。这些模型仍然可以与您的视图模型一起使用,并且为了保存我会调用一些服务或一些存储库,以便模型不知道数据库详细信息。

标签: c# wpf entity-framework mvvm


【解决方案1】:

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

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

所以你会:

  • 数据库
  • 连接到数据库的 Web 服务(使用 WCF)为您处理所有数据(我什至会让它也负责业务
  • 连接到 Web 服务的 WPF 应用程序:
    • 视图层是您的 XAML + 您的代码隐藏
    • ViewModel 层是您的 ViewModel(超出您的问题范围,但如果您对该层有任何疑问,请随时询问)。 ViewModel 异步调用 Web 服务
    • 模型是客户端 WCF 代理

这种方法的一些好处:

  • 根据硬件/网络结构,仅对服务器进行一次调用而不是 N 次调用可能会带来巨大的性能优势(假设 DB 和 Web 服务之间的延迟(均基于“服务器端”)低于 WPF 应用程序和数据库之间的)
  • 更具可扩展性
  • 无状态方法的所有好处:每个 Web 服务请求一个实体框架上下文实例化,因此更容易处理并发问题(如果您有 N 个 WPF 实例同时运行)
  • 更易于维护(层之间的松散耦合)
  • 更容易测试(假设您实际构建测试)
  • 更好的安全性(无需公开通过网络直接访问数据库)

【讨论】:

  • 但是如果客户需要将数据库保留在 Intranet 上...我可以在本地服务器上托管 WCF 服务吗,这是推荐的吗?如果我也使用 WCF 和直接数据库连接,那可能吗?有些客户只有 1 台计算机...内存不足...我认为 WCF 不适合它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-23
  • 1970-01-01
  • 2013-09-18
  • 2015-12-26
  • 2010-12-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多