.NET EF Core - 删除存储库和统一工作
.NET EF Core - Remove Repositories and Unity of Work
我使用 .NET 6.0 和 Blazor Server 创建了一个应用程序。有时我在我的应用程序中收到错误消息 在上一个操作完成之前在此上下文实例上启动了第二个操作。
我通常使用模式存储库。我有每个 table 的存储库和要保存的工作单元以及其他。在我之前的问题中向我解释说我使用 DbContext 不好。因为它在存储库和工作单元上共享 dbcontext。我阅读了很多文章,通常的建议是仅使用自定义 DbContext。我认为这对我来说不是问题。我需要对我的框架进行一些更改,但是 np.但我不明白一件事。我如何为每个 dbset 执行自定义通用查询?是否有很多关于将存储库与上下文工厂一起使用但没有统一工作的文章。我真的不喜欢所有操作都是独立的并且多次访问数据库的事实。
您的建议和经验是什么?你有关于这方面的文章或教程吗?
我真的只是在寻找如何让它成为“最好的”并且对我也有用。
非常感谢:)
DbContext
的设计为 short-lived。为每个操作创建一个新的上下文实例以解决您的问题。
您的 DbContext 应该是这样的,以便于构建。
public class SomeDbContext : DbContext
{
private readonly IConfiguration configuration;
public SomeDbContext(IConfiguration configuration)
{
this.configuration = configuration;
// this.Database.Migrate(); <- optional
}
DbSet<SomeValue> SomeValues { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
string connectionString =
this.configuration.GetConnectionString("DefaultConnection");
optionsBuilder.UseSqlServer(connectionString);
}
public async ValueTask<SomeValue> InsertSomeValueAsync(SomeValue someValue)
{
using var someDbContext = new SomeDbContext(this.configuration);
EntityEntry<SomeValue> entityEntry =
await someDbContext.SomeValues.AddAsync(entity: someValue);
await someDbContext.SaveChangesAsync();
return entityEntry.Entity;
}
}
InsertSomeValueAsync 方法很容易成为通用方法。
public async ValueTask<T> InsertSomeValueAsync<T>(T someValue)
where T : class
{
using var someDbContext = new SomeDbContext(this.configuration);
EntityEntry<T> entityEntry =
await someDbContext.AddAsync(someValue);
await someDbContext.SaveChangesAsync();
return entityEntry.Entity;
}
一种选择是使用 DBContextFactory
来管理上下文。
这是我的一个应用程序中的一些示例代码。
Program
var dbConnectionString = builder.Configuration.GetValue<string>("MyConfiguration:ConnectionString");
builder.Services.AddDbContextFactory<MySqlServerDbContext>(options => options.UseSqlServer(dbConnectionString), ServiceLifetime.Singleton);
并在(通用)数据代理中使用它:
public class ServerDataBroker
: IDataBroker
{
private IDbContextFactory<MySqlServerDbContext> _dbContextFactory;
public ServerDataBroker(IDbContextFactory<MySqlServerDbContext> factory)
=> _dbContextFactory = factory;
//.....
public async ValueTask<int> GetRecordCountAsync<TRecord>() where TRecord : class, new()
{
using var context = _dbContextFactory.CreateDbContext();
var dbSet = context.Set<TRecord>();
return dbSet is not null
? await dbSet.CountAsync()
: 0;
}
//.....
这里有一篇 MS-Docs 文章 - https://docs.microsoft.com/en-us/ef/core/dbcontext-configuration/。
在测试中,我使用 EF InMemory - 您可以将 Factory 与它一起使用。询问您是否希望被指向一些代码。
我使用 .NET 6.0 和 Blazor Server 创建了一个应用程序。有时我在我的应用程序中收到错误消息 在上一个操作完成之前在此上下文实例上启动了第二个操作。
我通常使用模式存储库。我有每个 table 的存储库和要保存的工作单元以及其他。在我之前的问题中向我解释说我使用 DbContext 不好。因为它在存储库和工作单元上共享 dbcontext。我阅读了很多文章,通常的建议是仅使用自定义 DbContext。我认为这对我来说不是问题。我需要对我的框架进行一些更改,但是 np.但我不明白一件事。我如何为每个 dbset 执行自定义通用查询?是否有很多关于将存储库与上下文工厂一起使用但没有统一工作的文章。我真的不喜欢所有操作都是独立的并且多次访问数据库的事实。
您的建议和经验是什么?你有关于这方面的文章或教程吗?
我真的只是在寻找如何让它成为“最好的”并且对我也有用。 非常感谢:)
DbContext
的设计为 short-lived。为每个操作创建一个新的上下文实例以解决您的问题。
您的 DbContext 应该是这样的,以便于构建。
public class SomeDbContext : DbContext
{
private readonly IConfiguration configuration;
public SomeDbContext(IConfiguration configuration)
{
this.configuration = configuration;
// this.Database.Migrate(); <- optional
}
DbSet<SomeValue> SomeValues { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
string connectionString =
this.configuration.GetConnectionString("DefaultConnection");
optionsBuilder.UseSqlServer(connectionString);
}
public async ValueTask<SomeValue> InsertSomeValueAsync(SomeValue someValue)
{
using var someDbContext = new SomeDbContext(this.configuration);
EntityEntry<SomeValue> entityEntry =
await someDbContext.SomeValues.AddAsync(entity: someValue);
await someDbContext.SaveChangesAsync();
return entityEntry.Entity;
}
}
InsertSomeValueAsync 方法很容易成为通用方法。
public async ValueTask<T> InsertSomeValueAsync<T>(T someValue)
where T : class
{
using var someDbContext = new SomeDbContext(this.configuration);
EntityEntry<T> entityEntry =
await someDbContext.AddAsync(someValue);
await someDbContext.SaveChangesAsync();
return entityEntry.Entity;
}
一种选择是使用 DBContextFactory
来管理上下文。
这是我的一个应用程序中的一些示例代码。
Program
var dbConnectionString = builder.Configuration.GetValue<string>("MyConfiguration:ConnectionString");
builder.Services.AddDbContextFactory<MySqlServerDbContext>(options => options.UseSqlServer(dbConnectionString), ServiceLifetime.Singleton);
并在(通用)数据代理中使用它:
public class ServerDataBroker
: IDataBroker
{
private IDbContextFactory<MySqlServerDbContext> _dbContextFactory;
public ServerDataBroker(IDbContextFactory<MySqlServerDbContext> factory)
=> _dbContextFactory = factory;
//.....
public async ValueTask<int> GetRecordCountAsync<TRecord>() where TRecord : class, new()
{
using var context = _dbContextFactory.CreateDbContext();
var dbSet = context.Set<TRecord>();
return dbSet is not null
? await dbSet.CountAsync()
: 0;
}
//.....
这里有一篇 MS-Docs 文章 - https://docs.microsoft.com/en-us/ef/core/dbcontext-configuration/。
在测试中,我使用 EF InMemory - 您可以将 Factory 与它一起使用。询问您是否希望被指向一些代码。