在 C# 控制台应用程序中访问 dbContext

spa*_*mac 8 c# dependency-injection console-application .net-core

我试图弄清楚这一点,但我被卡住了。

我有一个带有 Service/Repo/Api/Angular 层的 Net Core 2 应用程序 - 但现在我想“锁定”一个控制台应用程序并访问我已经建立的所有好东西。我似乎陷入了一堆静态对象和 DI 和 null 参数中。无论如何,这是我的代码的简化版本。

namespace SimpleExample
{

    class Program
    {

        private static ApplicationDbContext _appDbContext;

        public Program(ApplicationDbContext appDbContext)
        {
            _appDbContext = appDbContext;
        }

        static void Main(string[] args)
        {
            var instance = new Program();  // this doesn't work!
            var instance = new Program(_appDbContext);  // neither does this!
            instance.GetData();
        }


        private void GetData()
        {
            Console.WriteLine("Let's read some data! Press a key to continue.");
            Console.ReadLine();

            var data = "my data";
            var result = GetId(data);
        }


        private string GetId(string original)
        {
            var data = _appDbContext.Data
                .Where(x => x.Name == original.Trim)
                .FirstOrDefault();

            return data;

        }
    }

}
Run Code Online (Sandbox Code Playgroud)

我得到经典

'非静态字段需要一个对象引用'

错误。然后从这里调查开始,我把东西改成了静态,然后一切都变成了空。

这不仅仅是我试图注入的 DbContext。我也在尝试注入

私有 ManagerService _managerService;

但得到同样的错误。

更新

如果我尝试

私有静态 ApplicationDbContext _appDbContext = new ApplicationDbContext();

如以下几次建议,然后我收到错误

没有给出对应于“ApplicationDbContext.ApplicationDbContext( DbContextOptions )”所需形式参数“options”的参数

spa*_*mac 22

好的,我已经弄清楚了,我会为在这种情况下苦苦挣扎的其他人发布我的答案。

当您启动控制台应用程序时,正常的 startup.cs 不会执行,因此您必须在控制台应用程序中放置大量该代码。

    private static SiteService _siteService;
    private static ApplicationDbContext _appDbContext;

    public static void Main()
    {
        var services = new ServiceCollection();                      

        services.AddTransient<ISiteInterface, SiteRepo>();
        services.AddTransient<SiteService>();
        services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer("blah-blah"));            

        var serviceProvider = services.BuildServiceProvider();                                             
        _siteService = serviceProvider.GetService<SiteService>();
        _appDbContext = serviceProvider.GetService<ApplicationDbContext>();    
        GetData();
    }
Run Code Online (Sandbox Code Playgroud)

现在您的_appDbContext将在您的控制台应用程序的其余部分可用。

希望有帮助!

  • 它来自 * 使用 Microsoft.Extensions.DependencyInjection;* 将其添加到顶部。 (2认同)

小智 6

基本上,如果您不打算广泛使用 DbContext 也不使用 DI,则不需要 ServiceProvider。只需记住让 DbContext 实例短暂存在并将其用于单个工作单元,而不是更长的时间。

您的上下文可能如下所示:

using Microsoft.EntityFrameworkCore;

namespace YourNamespace;

public class ApplicationContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(@"Your conn string");
    }

    public DbSet<YourType> YourEntity { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

ApplicationContext您也可以通过 ctor 传递 conn 字符串。Microsoft对此进行了很好的解释。

然后你可以ApplicationContext像这样使用你的:

// Unit-of-work closed in using statement
// Here you can query/update your DbContext
using (var dbContext = new ApplicationContext())
{
    var queryResult = dbContext.YourEntity.Where(....);
}
Run Code Online (Sandbox Code Playgroud)

您可以准备多个此类工作单元作为查询数据库的单独方法。
您的存储库服务可以包含这些方法。
然后您可以根据需要实例化该服务。