Asp 核心,对象引用未设置为存储库模式中的对象实例
Asp core, Object reference not set to an instance of an object in Repository pattern
我正在开发 asp 核心 1.1,我想在我的项目中创建一个 select
存储库模式。
我在存储库中的代码 class :
public class AuthorReposetory : IDisposable
{
private static ApplicationDbContext _context;
public AuthorReposetory(ApplicationDbContext context)
{
_context = context;
}
public static List<Author> GetAuthorList()
{
List<Author> model = new List<Author>();
model = _context.authors.Select(a => new Author
{
AuthorId = a.AuthorId,
AuthorName = a.AuthorName,
AuthorDescription = a.AuthorDescription
}).ToList();
return model;
}
public void Dispose()
{
throw new NotImplementedException();
}
~AuthorReposetory()
{
Dispose();
}
}
并在控制器中
[HttpGet]
public IActionResult Index()
{
var q = AuthorReposetory.GetAuthorList();
return View(q);
}
更新
这是我的 StartUp Class
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//define Connection string
services.AddDbContext<ApplicationDbContext>(option => option.UseSqlServer(Configuration.GetConnectionString("DefualtConnection")));
//For Create and use identity in database
services.AddIdentity<ApplicationUser, ApplicationRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
// Add framework services.
services.AddMvc();
services.AddAutoMapper();
services.AddPaging();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseIdentity();
app.UseMvc(routes =>
{
//New Area For Admin
routes.MapRoute(
name: "Admin",
template: "{area:exists}/{controller=Admin}/{action=Index}/{id?}");
//New Area For User
routes.MapRoute(
name: "UserProfile",
template: "{area:exists}/{controller=UserProfile}/{action=Index}/{id?}");
//tranditional Routing
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
我的连接字符串在appsettings.json
{
"ConnectionStrings": {
"DefualtConnection" : "Data Source=.;Initial Catalog=DataBaseName;User ID = sa; Password = 123"
},
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Warning"
}
}
}
当存储库中 运行 model = _context.authors.Select(a => new Author
时,问题是 Object reference not set to an instance of an object
。
在上面我展示了控制器代码,存储库 class 代码和启动代码来弄清楚。
问题出在哪里?
注意:控制器中的一切都很好。只是问题在存储库 class.
可能您的 _context 对象为空。你的 DI/IoC 是如何配置的?我会这样调查的。
您的数据库上下文应该像这样添加:
public void ConfigureServices(IServiceCollection 服务)
{
services.AddDbContext(选项 => options.UseSqlite("Data Source=blog.db"));
}
以下是有关如何配置数据库上下文的文档:https://docs.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext
您尚未在 services
中注册存储库 class,因此无法通过容器解析。在你的 ConfigureServices
方法中试试这个:
services.AddScoped<AuthorReposetory>();
您正在使用静态方法并且从未调用构造函数,因为您从未创建对象。您必须将构造函数更改为:
public static AuthorReposetory()
{
_context = new ApplicationDbContext(options => options.UseSqlServer(Configuration.GetConnectionString("DefualtConnection")));
}
但这是非常糟糕的做法,因为您必须在构造函数中设置连接,并且这还会对您的上下文产生硬依赖性 class。
更好的解决方案是创建一个非静态 class
public class AuthorRepository : IAuthorRepository
{
private ApplicationDbContext _context;
public AuthorRepository(ApplicationDbContext context)
{
_context = context;
}
// ...
}
public interface IAuthorRepository
{
// ...
}
通过注入反转依赖:
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
//define Connection string and setup dependency injection
services.AddDbContext<ApplicationDbContext>(option => option.UseSqlServer(Configuration.GetConnectionString("DefualtConnection")));
services.AddScoped<IAuthorRepository, AuthorRepository>();
// ...
}
控制器:
public HomeController
{
private IAuthorRepository _authorRepository;
public HomeController(IAuthorRepository authorRepository)
{
_authorRepository = authorRepository;
}
[HttpGet]
public IActionResult Index()
{
var q = _autorRepository.GetAuthorList();
return View(q);
}
}
我正在开发 asp 核心 1.1,我想在我的项目中创建一个 select
存储库模式。
我在存储库中的代码 class :
public class AuthorReposetory : IDisposable
{
private static ApplicationDbContext _context;
public AuthorReposetory(ApplicationDbContext context)
{
_context = context;
}
public static List<Author> GetAuthorList()
{
List<Author> model = new List<Author>();
model = _context.authors.Select(a => new Author
{
AuthorId = a.AuthorId,
AuthorName = a.AuthorName,
AuthorDescription = a.AuthorDescription
}).ToList();
return model;
}
public void Dispose()
{
throw new NotImplementedException();
}
~AuthorReposetory()
{
Dispose();
}
}
并在控制器中
[HttpGet]
public IActionResult Index()
{
var q = AuthorReposetory.GetAuthorList();
return View(q);
}
更新
这是我的 StartUp Class
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//define Connection string
services.AddDbContext<ApplicationDbContext>(option => option.UseSqlServer(Configuration.GetConnectionString("DefualtConnection")));
//For Create and use identity in database
services.AddIdentity<ApplicationUser, ApplicationRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
// Add framework services.
services.AddMvc();
services.AddAutoMapper();
services.AddPaging();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseIdentity();
app.UseMvc(routes =>
{
//New Area For Admin
routes.MapRoute(
name: "Admin",
template: "{area:exists}/{controller=Admin}/{action=Index}/{id?}");
//New Area For User
routes.MapRoute(
name: "UserProfile",
template: "{area:exists}/{controller=UserProfile}/{action=Index}/{id?}");
//tranditional Routing
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
我的连接字符串在appsettings.json
{
"ConnectionStrings": {
"DefualtConnection" : "Data Source=.;Initial Catalog=DataBaseName;User ID = sa; Password = 123"
},
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Warning"
}
}
}
当存储库中 运行 model = _context.authors.Select(a => new Author
时,问题是 Object reference not set to an instance of an object
。
在上面我展示了控制器代码,存储库 class 代码和启动代码来弄清楚。
问题出在哪里?
注意:控制器中的一切都很好。只是问题在存储库 class.
可能您的 _context 对象为空。你的 DI/IoC 是如何配置的?我会这样调查的。
您的数据库上下文应该像这样添加:
public void ConfigureServices(IServiceCollection 服务) { services.AddDbContext(选项 => options.UseSqlite("Data Source=blog.db")); }
以下是有关如何配置数据库上下文的文档:https://docs.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext
您尚未在 services
中注册存储库 class,因此无法通过容器解析。在你的 ConfigureServices
方法中试试这个:
services.AddScoped<AuthorReposetory>();
您正在使用静态方法并且从未调用构造函数,因为您从未创建对象。您必须将构造函数更改为:
public static AuthorReposetory()
{
_context = new ApplicationDbContext(options => options.UseSqlServer(Configuration.GetConnectionString("DefualtConnection")));
}
但这是非常糟糕的做法,因为您必须在构造函数中设置连接,并且这还会对您的上下文产生硬依赖性 class。
更好的解决方案是创建一个非静态 class
public class AuthorRepository : IAuthorRepository
{
private ApplicationDbContext _context;
public AuthorRepository(ApplicationDbContext context)
{
_context = context;
}
// ...
}
public interface IAuthorRepository
{
// ...
}
通过注入反转依赖:
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
//define Connection string and setup dependency injection
services.AddDbContext<ApplicationDbContext>(option => option.UseSqlServer(Configuration.GetConnectionString("DefualtConnection")));
services.AddScoped<IAuthorRepository, AuthorRepository>();
// ...
}
控制器:
public HomeController
{
private IAuthorRepository _authorRepository;
public HomeController(IAuthorRepository authorRepository)
{
_authorRepository = authorRepository;
}
[HttpGet]
public IActionResult Index()
{
var q = _autorRepository.GetAuthorList();
return View(q);
}
}