在 .NET 6 中为 PostgreSQL 配置 DbContext

问题描述 投票:0回答:1

首先,我展示一下我的数据库相关类:

DbContext.cs

    public class BookingDbContext : DbContext
    {
        public BookingDbContext(DbContextOptions<BookingDbContext> options) : base(options)
        { }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
                optionsBuilder.UseNpgsql("Server=localhost;Port=5432;User Id=postgres;Password=password;Database=db");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder) 
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<Place>()
                .HasOne(p => p.Address)
                .WithOne(ad => ad.Place)
                .HasForeignKey<Address>(ad => ad.PlaceId)
                .OnDelete(DeleteBehavior.Cascade);
        }

        public DbSet<Place> Places { get; set; }
        public DbSet<Address> Addresses { get; set; }
    }

程序.cs


var builder = WebApplication.CreateBuilder(args);

builder.Services.AddDbContext<BookingDbContext>();

builder.Services.AddTransient<IPlaceService, PlaceService>();
builder.Services.AddTransient<IPlaceRepository, PlaceRepository>();

builder.Services.AddControllers().AddJsonOptions(options => options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles);

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.UseHttpsRedirection();

app.MapControllers();

app.Run();

我像往常一样创建了 CRUD 方法,因此添加、删除、更新和获取。前 3 种方法工作没有问题,只有 GET 失败。 我收到一条错误消息:

System.InvalidOperationException: No database provider has been configured for this DbContext. 
A provider can be configured by overriding the 'DbContext.OnConfiguring' method or by using 'AddDbContext' on the application service provider. 
If 'AddDbContext' is used, then also ensure that your DbContext type accepts a DbContextOptions<TContext> object in its constructor and passes it to the base constructor for DbContext.

你知道这可能是什么原因吗?正如我之前所说 - 当我向数据库添加或删除某些内容时,一切正常。仅对于 get 方法,我遇到了这样的错误。

编辑:

public async Task<IEnumerable<Place>> GetPlaces(bool includeAddress)
{
    if (includeAddress)
    {
       return await _dbContext.Places.Include(a => a.Address).ToListAsync();
    }
    else
    {
        return await _dbContext.Places.ToListAsync();
    }
}

public async Task<Place> GetById(int id)
{
   Place? place = await _dbContext.Places
                .Where(p => p.Id == id)
                .Include(p => p.Address)
                .FirstOrDefaultAsync();

   return place ?? throw new KeyNotFoundException($"Place with id: {id} not found.");
}
c# postgresql entity-framework .net-6.0
1个回答
0
投票

我的想法是,当您的 DbContext 服务注册为 Scoped 时,它的实例将像工作单元一样执行,并且生命周期很短。也许您的 GET 过程执行不止一项工作,并且在您的工作完成之前实例就已被释放。您可以尝试使用 AddDbContextFactory 方法:

builder.Services.AddDbContextFactory<BookingDbContext>();

并在 using 块中包含每个作业,创建 DbContext:

using (var db = _contextFactory.CreateDbContext())
{

 ...get operation code

}

这样db在所有get操作之后肯定会被处理掉。

© www.soinside.com 2019 - 2024. All rights reserved.