【问题标题】:What is the correct way of updating a record from the view model? [duplicate]从视图模型更新记录的正确方法是什么? [复制]
【发布时间】:2017-02-07 22:01:02
【问题描述】:

仍在开发我的第一个 UWP/MVVM/EF Core 应用程序。

我不希望我的视图模型对 DbContext 有任何了解。所以我创建了以下 ItemService 类,注入到我的视图模型中。

public class ItemService : IItemService
{
    public async Task SaveAsync(Item item)
    {
        using (var db = new MyDbContext())
        {
            db.Items.Add(item);
            await db.SaveChangesAsync();
        }
    }
}

我的 ItemViewModel 包含以下命令:

public RelayCommand SaveCommand { get; private set; }

private async void Save()
{
    if (!SaveCommand.CanExecute(Item))
        return;

    await ItemService.SavAsync(Item);
}

这在我保存项目时非常有用。 SaveAsync 方法创建 DbContext 的新实例,添加刚刚创建的项目,然后将更改提交到数据库。

我的问题是关于现有记录的更新。我想这样的事情:

public class ItemService : IItemService
{
    public async Task UpdateAsync(Item item)
    {
        using (var db = new MyDbContext())
        {
            Item dbItem = (from i in db.Items
                           where i.Id = item.Id
                           select i).FirstOrDefault();

            // Here I should duplicate all the item's properties into dbItem ones

            await db.SaveChangesAsync();
        }
    }
}

我就是不喜欢这个解决方案! 我必须将项目的所有属性复制到 dbItem 中。如果我忘记了怎么办?我可以实现 ICloneable,但我发现为我的所有实体执行此操作确实需要开销。

那么这里的正确模式是什么。更新由视图模型管理的记录的最佳方式?

提前非常感谢, 朱利安

【问题讨论】:

  • 我几乎看不到“更好”的方法,毕竟这就是更新。您可以检查每个属性以避免重写那些没有更改的属性,但是,您仍然必须在某个时候处理每个属性。
  • 您可以使用 Automapper automapper.org 来避免任何映射问题
  • Automapper 是无赖的最后避难所。不要使用它。您真正的问题是“如何更新 EF 核心中的分离模型?”它实际上与 wpf 和 mvvm 没有任何关系。
  • (请注意,Automapper 适合将字段从一个对象实例复制到另一个,但将实例重新连接到上下文是更好的选择。我会回答,但我不知道 EF Core 是否在这方面与我知道的 EF 6 不同)

标签: c# mvvm uwp entity-framework-core


【解决方案1】:

您必须在您的应用程序上使用存储库模式。然后您可以将 DAL 层与 ViewmModels 完全解耦。在服务层上,您可以使用 AutoMapper 将 ViewModel 映射到实体,反之亦然。此时您可以做到在您的服务层上。但是您必须使用依赖注入为存储库模式(即 DAL)引入单独的层。然后您不必担心虚拟机和实体的混合。换句话说,它们位于 2 个单独的层上如果您实现上述模式。

因此您使用的是 EF 核心,您可以使用 Autofac 作为 DI API。

什么是 AutoMapper?

AutoMapper 是一个简单的小库,用于解决欺骗性问题 复杂的问题 - 摆脱将一个对象映射到的代码 其他。这种类型的代码写起来相当枯燥乏味,所以 为什么不发明一种工具来为我们做这件事呢?

这里是链接:AutoMapper

好文章:Generic Repository and Unit of Work Pattern, Entity Framework,Autofac

根据 @Sean Stayn 的建议,您可以在其中使用 Prism。也请参阅。

Prism 是一个框架,用于构建松散耦合、可维护和 WPF、Windows 10 UWP 和 Xamarin 表单中的可测试 XAML 应用程序。

【讨论】:

  • 如果你使用 AutoFac 和依赖注入,我推荐 Prism 6 用于 UWP。从 DI 和 UWP 入手很有帮助!
  • 我不同意你的观点。这是来自 OP I have to copy all the properties of item into dbItem. What if I forgot one ?。然后Automapper 会做他需要做的事情。B'cos 如果你正确配置Automapper,那么它永远不会忘记要映射的任何属性:D @Will
  • 啊,我明白你从哪里来了。但是,他所要做的就是重新附加模型并将其标记为已更改。这比导入新的依赖项要简单得多。但这是一种解决方案,是的。
  • 呵呵..那你可以Up vote insted of Down vote 不? :D @Will
  • 我根本没有投票...我说“我想投反对票”。我撤回我的投诉并将其删除,以确保我不会混淆任何访客。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-01
  • 1970-01-01
  • 2018-05-30
  • 1970-01-01
  • 1970-01-01
  • 2017-03-03
相关资源
最近更新 更多