Dan*_*len 16 c# entity-framework asp.net-core-mvc
我该如何将我的MyDbContext注入我的数据库服务层MyService?
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<MyDbContext>(options =>
options.UseSqlServer(Configuration["ConnectionStrings:DefaultConnection"]));
services.AddMvc();
}
Run Code Online (Sandbox Code Playgroud)
MyDbContext.cs
public partial class MyDbContext : DbContext
{
public virtual DbSet<User> User { get; set; }
public MyDbContext(DbContextOptions<MyDbContext> options)
:base(options)
{
}
}
Run Code Online (Sandbox Code Playgroud)
appsettings.json
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
"ConnectionStrings": {
"DefaultConnection": "Server=MyServer;Database=MyDatabase;user id=MyUser;password=MyPassword;"
}
}
Run Code Online (Sandbox Code Playgroud)
MyService.cs
public class MyService
{
public User GetUser(string username)
{
// Should i remove this call and get the reference from the injection somehow?
MyDbContext db_context = new MyDbContext(optionsBuilder.Options);
using (db_context)
{
var users = from u in db_context.User where u.WindowsLogin == username select u;
if (users.Count() == 1)
{
return users.First();
}
return null;
}
}
}
Run Code Online (Sandbox Code Playgroud)
在我的GetUser方法中,我知道我应该使用我MyDbContext在这里注入,但我不太确定如何获取它.我错过了哪一块拼图?
Adr*_*ris 31
您不必自己包含dbcontext,ASP.NET核心依赖注入服务将为您执行此操作.
您只需在启动类中声明服务和数据库上下文,并将所需的dbcontext放在服务的构造函数中:
Startup.cs(你必须选择你想要的服务生命周期,这里它是一个范围的服务,每个请求一次):
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<MyDbContext>(options =>
options.UseSqlServer(Configuration["ConnectionStrings:DefaultConnection"]));
services.AddMvc();
services.AddScoped<IMyService, MyService>();
}
Run Code Online (Sandbox Code Playgroud)
您的服务类:
public class MyService : IMyService
{
private readonly MyDbContext _context;
public MyService(MyDbContext ctx){
_context = ctx;
}
public User GetUser(string username)
{
var users = from u in _context.User where u.WindowsLogin == username select u;
if (users.Count() == 1)
{
return users.First();
}
return null;
}
}
public interface IMyService
{
User GetUser(string username);
}
Run Code Online (Sandbox Code Playgroud)
在您的控制器中,您必须以相同的方式声明您需要使用的服务(或数据库上下文):
public class TestController : Controller
{
private readonly IMyService _myService;
public TestController(IMyService serv)
{
_myService = serv;
}
public IActionResult Test()
{
return _myService.MyMethod(); // No need to instanciate your service here
}
}
Run Code Online (Sandbox Code Playgroud)
关于控制器的注意事项:您不必像在数据库环境或服务中那样在启动类中添加它们.只需实现他们的构造函数.
如果您需要有关.NET Core依赖注入的更多信息,官方文档清晰且非常完整:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection
注意: 在startup.cs中,AddScoped行是一个选项.您可以选择所需的服务期限.您可以选择不同的生命周期:
短暂的
每次请求时都会创建瞬态生命周期服务.这种生命周期最适合轻量级无状态服务.
作用域
每个请求创建一次范围生命周期服务.
独生子
Singleton生命周期服务是在第一次请求时创建的(或者当您在那里指定实例时运行ConfigureServices时),然后每个后续请求将使用相同的实例.
以上摘自:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection
注意:这不是问题,但您的GetUser数据查询对我来说有点奇怪.如果你的count()== 1目标是检查用户的唯一性,那么好的方法是在数据库中添加unicity约束.如果count()== 1目标是检查你有数据以避免对象空引用异常,你可以使用.FirstOrDefault(),它会为你管理这个.您可以简化此方法:
public User GetUser(string username) => (from u in _context.User where u.WindowsLogin == username select u).FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15929 次 |
| 最近记录: |