.NET 6 WPF应用中如何实现Services.AddDbContext?
在.NET 6 WPF应用中配置内存数据库的方案
核心思路
WPF不像ASP.NET Core默认自带DI容器,但可以通过Microsoft.Extensions.DependencyInjection搭建依赖注入环境,然后复用和ASP.NET一致的内存数据库注册逻辑;也可以直接手动实例化DbContext,无需DI。
方案一:基于DI容器配置(推荐复杂项目)
1. 安装必要NuGet包
需要安装以下包:
Microsoft.EntityFrameworkCoreMicrosoft.EntityFrameworkCore.InMemoryMicrosoft.Extensions.DependencyInjection
2. 在App.xaml.cs中配置DI与DbContext
using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using System.Windows; namespace YourWpfProject { public partial class App : Application { private IServiceProvider _serviceProvider; protected override void OnStartup(StartupEventArgs e) { // 初始化服务集合 var services = new ServiceCollection(); // 注册内存数据库版DbContext,逻辑和ASP.NET完全一致 services.AddDbContext<MyContext>(options => { options.UseInMemoryDatabase("MyInMemoryDb"); }); // 注册视图模型、窗口等(按需添加) services.AddTransient<MainWindow>(); services.AddTransient<MainWindowViewModel>(); // 构建服务提供器 _serviceProvider = services.BuildServiceProvider(); // 从DI获取主窗口并显示 var mainWindow = _serviceProvider.GetRequiredService<MainWindow>(); mainWindow.Show(); } // 提供全局获取服务的方法(按需) public T GetService<T>() where T : class { return _serviceProvider.GetService<T>(); } } }
3. 定义DbContext实体
using Microsoft.EntityFrameworkCore; namespace YourWpfProject { public class MyContext : DbContext { public MyContext(DbContextOptions<MyContext> options) : base(options) { } // 定义你的业务实体集合 public DbSet<Product> Products { get; set; } } // 示例实体 public class Product { public int Id { get; set; } public string Name { get; set; } } }
4. 在ViewModel中注入使用DbContext
using System.Collections.ObjectModel; using System.Windows.Input; namespace YourWpfProject { public class MainWindowViewModel { private readonly MyContext _dbContext; public ObservableCollection<Product> Products { get; set; } = new(); public ICommand AddProductCommand { get; } // 通过构造函数注入DbContext public MainWindowViewModel(MyContext dbContext) { _dbContext = dbContext; LoadProducts(); AddProductCommand = new RelayCommand(AddProduct); } private void LoadProducts() { Products.Clear(); foreach (var product in _dbContext.Products) { Products.Add(product); } } private void AddProduct() { var newProduct = new Product { Name = $"商品{Products.Count + 1}" }; _dbContext.Products.Add(newProduct); _dbContext.SaveChanges(); Products.Add(newProduct); } } // 基础RelayCommand实现(按需替换为自己的命令类) public class RelayCommand : ICommand { private readonly Action _execute; private readonly Func<bool> _canExecute; public event EventHandler CanExecuteChanged; public RelayCommand(Action execute, Func<bool> canExecute = null) { _execute = execute ?? throw new ArgumentNullException(nameof(execute)); _canExecute = canExecute; } public bool CanExecute(object parameter) { return _canExecute == null || _canExecute(); } public void Execute(object parameter) { _execute(); } public void RaiseCanExecuteChanged() { CanExecuteChanged?.Invoke(this, EventArgs.Empty); } } }
方案二:手动实例化DbContext(适合简单场景)
如果不需要DI,可直接创建DbContext实例:
// 配置内存数据库选项 var dbOptions = new DbContextOptionsBuilder<MyContext>() .UseInMemoryDatabase("MyInMemoryDb") .Options; // 实例化DbContext并使用 using var dbContext = new MyContext(dbOptions); // 示例操作:添加数据 dbContext.Products.Add(new Product { Name = "测试商品" }); dbContext.SaveChanges();
关键注意事项
- 内存数据库的生命周期:基于DI的方式中,DbContext的生命周期由DI容器管理;手动实例化的方式中,DbContext销毁后数据会保留(直到应用进程结束,或重新创建同名内存数据库)。
- 若需要多实例共享同一内存数据库,确保使用相同的数据库名称(即
UseInMemoryDatabase的参数)。
内容的提问来源于stack exchange,提问作者Rod
相关产品推荐
相关产品推荐

