如何从ASP.NET Core中的另一个类访问DataContext?

时间:2016-08-12 05:35:18

标签: c# asp.net-core

我创建了一个类,因此我可以查询我的数据。如果我在控制器类中执行它数据上下文工作,但如果我在我创建的类中执行它会抛出null错误。它会引发以下错误:

  

Microsoft.Extensions.DependencyInjection.Abstractions.dll但未在用户代码中处理

我的启动配置:

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddApplicationInsightsTelemetry(Configuration);

    services.AddDbContext<Abstractor_DataContext>(options =>
       options.UseSqlServer(Configuration.GetConnectionString("ApplicationDatabase")));

    //services.AddTransient(typeof(Abstractor_DataContext));


    //Register your filter as a service (Note this filter need not be an attribute as such)
    services.AddTransient<AppExceptionFilterAttribute>();

    services.AddMvc();
}

我的类函数访问DataContext

using Microsoft.Extensions.DependencyInjection;
public static IList<ApplicationInfo> TestDb()
{
    //var options = _serviceProvider.GetService<Abstractor_DataContext>();
    using (var context = _serviceProvider.GetService<Abstractor_DataContext>())
    {
        return context.ApplicationInfo.ToList();
    }
}

var context为空。我错过了什么?我正在慢慢学习DI。

2 个答案:

答案 0 :(得分:4)

根据基于新数据库的ASP.net核心项目的official documentation,首先需要创建模型和DbContext:

using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;

namespace EFGetStarted.AspNetCore.NewDb.Models
{
    public class BloggingContext : DbContext
    {
        public BloggingContext(DbContextOptions<BloggingContext> options)
            : base(options)
        { }

        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }
    }

    public class Blog
    {
        public int BlogId { get; set; }
        public string Url { get; set; }

        public List<Post> Posts { get; set; }
    }

    public class Post
    {
        public int PostId { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }

        public int BlogId { get; set; }
        public Blog Blog { get; set; }
    }
}

然后,使用依赖注入注册您的上下文:

public void ConfigureServices(IServiceCollection services)
        {
            var connection = @"Server=(localdb)\mssqllocaldb;Database=EFGetStarted.AspNetCore.NewDb;Trusted_Connection=True;";
            services.AddDbContext<BloggingContext>(options => options.UseSqlServer(connection));

然后使用数据库迁移创建数据库。现在,您使用构造函数创建控制器,将上下文作为参数之一(注释构造函数参数中的BloggingContext context)。

using EFGetStarted.AspNetCore.NewDb.Models;
using Microsoft.AspNetCore.Mvc;
using System.Linq;

namespace EFGetStarted.AspNetCore.NewDb.Controllers
{
    public class BlogsController : Controller
    {
        private BloggingContext _context;

        public BlogsController(BloggingContext context)
        {
            _context = context;
        }

        public IActionResult Index()
        {
            return View(_context.Blogs.ToList());
        }

        public IActionResult Create()
        {
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult Create(Blog blog)
        {
            if (ModelState.IsValid)
            {
                _context.Blogs.Add(blog);
                _context.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(blog);
        }

    }
}

在任何类中使用DbContext在控制器中使用它是相同的。您需要将您的类注册到依赖注入器。它是用ConfigureServices方法完成的。 This page from official docs包含详细信息。以下是注册服务类实现的一些示例:

services.AddScoped<ICharacterRepository, CharacterRepository>();
services.AddTransient<IOperationTransient, Operation>();
services.AddScoped<IOperationScoped, Operation>();
services.AddSingleton<IOperationSingleton, Operation>();
services.AddSingleton<IOperationSingletonInstance>(new Operation(Guid.Empty));
services.AddTransient<OperationService, OperationService>();

答案 1 :(得分:0)

就像很多人说的那样(同样在related question中),在SOLID中访问模型中的数据上下文是一种反模式-但在某些项目中可能有意义。

可以注入依赖项into the view,然后注入模型。这样就不必为每个模型注册服务。

以下示例说明了从模型访问视图的下拉值的数据库。

查看

private readonly MyDataContext db;
public MyClass(MyDataContext context)
{
    db = context;
}

// class properties...    

public IEnumerable<SelectListItem> MyModelFunc()
{
    List<SelectListItem> ddlb = db.MyClass.Select(x => new SelectListItem { Value = x.ID, Text = x.name}).ToList();
    return new SelectList(ddlb , "Value", "Text");
}

模型

{{1}}