如何访问Asp.net核心服务的DbContext

用户名

我对ASP.NET核心和实体框架及其所有(其他)组件的使用感到有些困惑。我正在开发一个简单的网络应用程序,您可以在其中输入一些数据并让其计算一些统计信息(基本上是strava ultra-light)。

因此,如果我从Visual Studio(2019)打开默认的blazor应用程序,则会得到类似Startup的信息

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using BlazorApp1.Areas.Identity;
using BlazorApp1.Data;

namespace BlazorApp1
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")));
            services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
                .AddEntityFrameworkStores<ApplicationDbContext>();
            services.AddRazorPages();
            services.AddServerSideBlazor();
            services.AddScoped<AuthenticationStateProvider, RevalidatingIdentityAuthenticationStateProvider<IdentityUser>>();
            services.AddSingleton<WeatherForecastService>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
                endpoints.MapBlazorHub();
                endpoints.MapFallbackToPage("/_Host");
            });
        }
    }
}

像这样的服务

using System;
using System.Linq;
using System.Threading.Tasks;

namespace BlazorApp1.Data
{
    public class WeatherForecastService
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        public Task<WeatherForecast[]> GetForecastAsync(DateTime startDate)
        {
            var rng = new Random();
            return Task.FromResult(Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = startDate.AddDays(index),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            }).ToArray());
        }
    }
}

所以我为我的数据添加了一个模型

using Microsoft.AspNetCore.Identity;
using BlazorApp1.Database.Types;
using System.ComponentModel.DataAnnotations;

namespace BlazorApp1.Database.Entity
{
    public class Activity
    {
        public string ActivityData { get; set; }
        public ActivityType ActivityType { get; set; }
        public float Distance { get; set; }

        [Key]
        public int Id { get; private set; }

        public IdentityUser User { get; set; }
    }
}

并将其添加到ApplicationDbContext

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;

namespace BlazorApp1.Data
{
    public class ApplicationDbContext : IdentityDbContext
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {
        }

        public DbSet<Activity> Activities { get; set; }
    }
}

所以现在我想创建自己的类似于WeatherForecastService的服务,这就是我遇到的问题。

using log4net;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using BlazorApp1.Data.Model;
using BlazorApp1.Database;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace BlazorApp1.Data
{
    public class LeaderBoardService
    {
        private readonly static ILog _logger = LogManager.GetLogger(typeof(LeaderBoardService));


        public Task<List<LeaderBoardItem>> GetOverallLeaderboard()
        {
            //I want to access the database context from here.
            return Task.FromResult(result);
        }
    }
}

另外,我需要将此服务添加到Startup.ConfigureServices()。到目前为止,我发现我可以使用services.AddScoped<LeaderBoardService>()services.AddSingleton<LeaderBoardService>()services.AddTransient<LeaderBoardService>()完成此操作,这似乎services.AddScoped<LeaderBoardService>()是最好的用法。

可能只有我一个人有这个问题,但是文档似乎缺少有关如何完成此看似简单的任务的提示。

到目前为止,我查看了以下站点:

  1. https://docs.microsoft.com/zh-cn/aspnet/core/data/ef-rp/intro?view=aspnetcore-3.1&tabs=visual-studio
    • 但此示例中未使用任何服务。
  2. https://docs.microsoft.com/zh-cn/ef/core/miscellaneous/configuring-dbcontext#using-dbcontext-with-dependency-injection
    • 尽管似乎解决方案只是将上下文作为参数添加到服务的构造函数中,但我似乎找不到在任何调用期间如何添加此参数的方法。
  3. https://stackoverflow.com/a/48698290
    • 我不是100%不确定这是否是我要寻找的东西,但事实证明我想对如何实现这一点有所提示。
  4. 类内的asp.net核心访问dbcontext
    • 这里使用了一些中间件,我想这不是我想要的。
  5. https://stackoverflow.com/a/44484724/2986756
    • 这是使DbContext成为瞬态对象的一种选择,而不是我想要的。
  6. https://stackoverflow.com/a/37511175
    • 此处,数据库放置在Singleton中。尽管我可以使用它,但我认为我不应该这样做。
阿尔曼·埃布拉辛普

LeaderBoardService应通过以下方式实现:

public class LeaderBoardService
{
    private readonly ApplicationDbContext dbContext;
    private readonly ILogger logger;

    public LeaderBoardService(ApplicationDbContext dbContext, ILogger<LeaderBoardService> logger)
    {
        this.dbContext = dbContext;
        this.logger = logger;
    }

    public async Task<List<LeaderBoardItem>> GetOverallLeaderboard()
    {
        return await dbContext.LeaderBoardItems.ToListAsync();
    }
}

关于您的服务生命周期,这取决于您的使用情况,但是绝对不应超过其内部服务生命周期。因此,您的服务可以是scopedtransient,但不是singleton因为您的DbContext声明为scoped(当然,singleton由于并发问题,您绝不应该将DbContext声明为)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在ASP.NET核心服务中使用*关键字

如何在Linux上启动Asp.net核心服务器并保持其运行

Azure Linux WebApp上的ASP.NET Core核心服务

您应该如何根据依赖关系树来处理.net核心服务?

如何获取.net核心服务器名称和选项

在无状态的asp.net核心服务结构应用程序中读取appsettings.json

获取 Azure Asp.Net 核心服务器上图像的文件路径(在控制器中)

Websockets 连接仅在 Chrome 使用子协议访问 ASP 核心服务器时失败

如何在对ASP.NET核心服务器的POST请求的正文中使用字符串化的枚举?

无法将文件〜200mb上传到asp.net核心服务器端的Azure Blob存储中

在ASP.NET核心中使用时,如何从另一个项目访问EF核心的DbContext?

带有nginx和.NET核心服务的Service Fabric

如何将范围服务注入DbContext?网络核心

如何访问 ASP.NET API 密钥?

如何访问cookie asp.net core

如何停止 Azure 事件中心服务?

访问被拒绝的文件在asp.net核心

仅允许从 ASP.NET 核心 Web 服务中的特定 url 访问

如何在ASP.net Web服务中访问Microsoft Outlook服务

如何从类访问Asp.net Core DI容器

如何从ASP.NET中的任何类访问会话变量?

如何访问ASP.Net Repeater中的特定控件

ASP.NET WebForms-如何授权对页面的访问

如何从ASP .NET Core MVC 1.0中的视图访问会话

如何从任何ASP .Net Core类访问当前的绝对Uri?

如何获得对Asp.Net Core加密密钥的访问?

如何在ASP.NET 5 MVC中访问缓存?

如何从ASP.NET中的表单访问字段数组?

如何通过实体框架访问多对多表?asp.net