C# 如何从ASP.NET Core中的另一个类访问DataContext?
我创建了一个类以便查询数据。如果我在控制器类数据上下文中这样做,但如果我在创建的类中这样做,它会抛出null错误。它抛出以下错误: Microsoft.Extensions.DependencyInjection.Abstractions.dll,但未在用户代码中处理 我的启动配置:C# 如何从ASP.NET Core中的另一个类访问DataContext?,c#,asp.net-core,C#,Asp.net Core,我创建了一个类以便查询数据。如果我在控制器类数据上下文中这样做,但如果我在创建的类中这样做,它会抛出null错误。它抛出以下错误: Microsoft.Extensions.DependencyInjection.Abstractions.dll,但未在用户代码中处理 我的启动配置: public void ConfigureServices(IServiceCollection services) { // Add framework services. services.Ad
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();
}
public void配置服务(IServiceCollection服务)
{
//添加框架服务。
services.AddApplicationInsightsTelemetry(配置);
services.AddDbContext(选项=>
options.UseSqlServer(Configuration.GetConnectionString(“ApplicationDatabase”));
//AddTransient(typeof(Abstractor_DataContext));
//将筛选器注册为服务(注意,此筛选器本身不必是属性)
services.AddTransient();
services.AddMvc();
}
My class函数来访问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();
}
}
使用Microsoft.Extensions.DependencyInjection;
公共静态IList TestDb()
{
//var options=_serviceProvider.GetService();
使用(var context=\u serviceProvider.GetService())
{
返回context.ApplicationInfo.ToList();
}
}
var上下文
为空。我错过了什么?我正在慢慢地学习DI 根据新的基于DB的ASP.net核心项目,首先需要创建模型和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; }
}
}
在任何类中使用DbContext与在控制器中使用它是相同的。您需要将类注册到依赖项注入器。这是在ConfigureServices
方法中完成的。包含详细信息。以下是注册服务类实现的一些示例:
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>();
services.addScope();
services.AddTransient();
services.addScope();
services.AddSingleton();
AddSingleton(新操作(Guid.Empty));
services.AddTransient();
正如许多人所说(在a中也是如此),访问模型中的数据上下文在SOLID中是一种反模式,但在某些项目中可能是有意义的
可以先注入依赖项,然后再注入模型,这样就不必为每个模型注册服务
下面的示例演示如何从模型访问数据库以获取视图的下拉值
查看:
@model MyProject.Models.MyClass
@inject MyDataContext db
@{
ViewData["Title"] = "Create";
MyClass tmp = new MyClass(db);
}
<!-- Markup... -->
<select asp-for="MyField" class="form-control" asp-items="tmp.MyModelFunc()"></select>
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");
}
@model MyProject.Models.MyClass
@注入MyDataContext数据库
@{
ViewData[“标题”]=“创建”;
MyClass tmp=新的MyClass(db);
}
型号:
@model MyProject.Models.MyClass
@inject MyDataContext db
@{
ViewData["Title"] = "Create";
MyClass tmp = new MyClass(db);
}
<!-- Markup... -->
<select asp-for="MyField" class="form-control" asp-items="tmp.MyModelFunc()"></select>
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");
}
private只读MyDataContext数据库;
公共MyClass(MyDataContext上下文)
{
db=上下文;
}
//类属性。。。
公共IEnumerable MyModelFunc()
{
List ddlb=db.MyClass.Select(x=>newselectListItem{Value=x.ID,Text=x.name}).ToList();
返回新的选择列表(ddlb,“值”、“文本”);
}
您没有将DbContext作为输入,因此它无法向您提供DbContext对象。您何时使用此TestDb
方法?如果在调用此方法时数据上下文已经注册,那么它应该可以工作。但在这个例子中,若你们在数据库Seed
期间调用这个函数,它将不起作用。[HttpGet][Route(“GetTestDb”)]public IList GetTestDb(int id){return DataAccessServices.TestDb();/_context.ApplicationInfo.ToList()}OP希望访问控制器外部的上下文。不是这样的。三菊谢谢你的意见。我确实使用EF创建了模型。如果像您提供的示例一样访问控制器类中的数据上下文,那么一切都可以正常工作,但是如果我尝试在另一个不是控制器的类中使用数据上下文,则会抛出错误。阅读文档时说使用iSeries调用dbcontext服务并添加microsoft扩展DI包,但这仍然会引发错误,并说上下文为空。更新了答案,在服务类(控制器类之外)中使用DI使用dbcontext。谢谢,它现在可以工作了。我创建了接口类,然后将其注册到startup.cs文件中。一个问题是,你必须有接口类,还是可以注册没有接口的类?你可以注册没有接口的类。使用services.AddScoped()代码>我认为使用接口是一种很好的设计模式,因为接口
抽象了实际的实现,您将能够使用接口轻松地更改实现,而无需对调用类中的依赖项需求进行任何更改,因为它们取决于接口。