gpt4 book ai didi

c# - 如何从 asp.net 核心服务访问 DbContext

转载 作者:行者123 更新时间:2023-12-05 03:52:21 26 4
gpt4 key购买 nike

我对 ASP.NET 核心和 Entity Framework 及其所有(其他)组件的使用有点困惑。我正在开发一个简单的网络应用程序,您可以在其中输入一些数据并让它计算一些统计数据(基本上是 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://learn.microsoft.com/en-us/aspnet/core/data/ef-rp/intro?view=aspnetcore-3.1&tabs=visual-studio
    • 但此示例中没有使用任何服务。
  2. https://learn.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext#using-dbcontext-with-dependency-injection
    • 虽然看起来解决方案只是将上下文作为参数添加到服务的构造函数中,但我似乎无法找到如何在任何调用期间添加此参数。
  3. https://stackoverflow.com/a/48698290
    • 我不是 100% 确定这是否是我正在寻找的东西,但如果事实证明是这样,我想获得一些关于如何实现它的提示。
  4. asp.net core access dbcontext within class
    • 这里使用了一些中间件,我想这不是我要找的。
  5. https://stackoverflow.com/a/44484724/2986756
    • 这是一个使 DbContext transient 化的选项,也不是我要找的。
  6. https://stackoverflow.com/a/37511175
    • 这里数据库被放置在一个单例中。虽然我可以使用它,但我认为我不应该。

最佳答案

您的 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(并且当然,由于并发问题,您永远不应该将 DbContext 声明为 singleton

关于c# - 如何从 asp.net 核心服务访问 DbContext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62248803/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com