使用界面

时间:2015-06-20 15:47:30

标签: c# wpf database entity-framework mvvm

[编辑]在阅读之前,我已经设法通过简单地转换不同的数据类来解决这个问题。 我已经更新了有效的代码,但欢迎您提出建议!

亲爱的stackoverflow用户,

我想首先说我明白这个问题很可能与Automapper相关。 不幸的是......由于某种原因,NuGet不愿意安装Automapper。 因此,我决定尝试在DTO和实体之间编写手动映射器。 我是IoC和DI的新手,我猜这是我的实现不正确的主要原因。

基本上我有5个以上不同的数据网格,其中所有数据网格都链接到不同的表格,因此具有不同的结构。 但是,它们都具有完全相同的消息处理程序,这些消息处理程序指向viewmodel中的相同方法,这些方法将负责添加,删除和修改。

处理删除的代码如下所示。

在viewmodel中:

 public void KeyDown(EventArgs eventArgs, object sourceSender)
    {
        var dataGridContext = sourceSender as DataGrid;
        var keyEventArgs = eventArgs as KeyEventArgs;
        if (keyEventArgs == null) return;
        switch (keyEventArgs.Key)
        {
            case Key.Delete:
                if (dataGridContext != null)
                        foreach (var selectedEntity in dataGridContext.SelectedItems.OfType<IEntityObject>())
                        {
                            _mainModel.DeletePendingEntityObject(selectedEntity);
                        }
                break;
        }
    }

在模型中:

    public void DeletePendingEntityObject<TEntity>(TEntity sender) where TEntity : IEntityObject
    {
         if (sender.State == EntityState.Added)
         {
             _pendingEntityObjects.Remove(sender);
             return;
         }
         AddPendingEntityObject(sender, EntityState.Deleted);
    }

处理添加和修改的代码如下所示:

在viewmodel中:

 public void RowEditEnding(object sender)
    {
        var dataGridContext = sender as DataGrid;
        if (_isNewItem && dataGridContext != null)
        {
            var item = dataGridContext.CurrentItem as IEntityObject;
            _mainModel.AddPendingEntityObject(item, EntityState.Added);
            _isNewItem = false;
        }

        else if (dataGridContext != null)
        {
            var item = dataGridContext.CurrentItem as IEntityObject;
            if (item == null) return;
            _mainModel.AddPendingEntityObject(item, EntityState.Modified);
        }
    }

在模型中:

    public void AddPendingEntityObject<TEntity>(TEntity sender,
 EntityState entityState) where TEntity : IEntityObject
    {
        sender.State = entityState;
        _pendingEntityObjects.Add(sender);
    }

现在,所有这一切都完美无缺,直到我想创建一个映射器,将DTO对象映射到它们的实体以将其保存到数据库。 我相信实现是不正确的,因为我必须在接口中添加我想在DtoMapper.cs中映射的每个属性(如下所示)。最终所有DTO的变量都与它们无关。

这是我的尝试:

 foreach (var item in _pendingEntityObjects)
            {
                using (var context = new CentralEntities())
                {
                    var entityObj = new DtoMapper<IEntityObject>(item);
                    context.Entry(entityObj.TranslatedObj).State = item.State;
                    context.SaveChanges();
                }
            }

这就是DtoMapper.cs的样子:

    public DtoMapper(T t)
    {
        if (t.GetType() == typeof(Table1Dto))
        {
            var table1Obj = t as Table1Dto;
            if(table1Obj != null)
            TranslatedObj = new table_1
            {
                id = table2Obj.Id,
                table1Code = table1Obj.Table1Code,
                reference = table1Obj.Reference
            };
        }
        else if (t.GetType() == typeof (Table2Dto))
        {
            var table2Obj = t as Table2Dto;
            if(table2Obj != null)
            TranslatedObj = new table_2
            {
                id = table2Obj.Id,
                table2Code = table2Obj.Table2Code,
                reference = table2Obj.Reference
            };
        }
    }

    public object TranslatedObj { get; set; }

我如何解决这个问题以保持代码干净,以及适用于任何数据网格的通用方法/映射器? 提前谢谢!

1 个答案:

答案 0 :(得分:0)

检查抽象工厂设计模式。您应该创建一个工厂来解析您的通用T型DTO的映射器。

https://en.wikipedia.org/wiki/Abstract_factory_pattern