我创建了一个类,因此我可以查询我的数据。如果我在控制器类中执行它数据上下文工作,但如果我在我创建的类中执行它会抛出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。
答案 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}}