![](/img/trans.png)
[英]EF Core: The instance of entity type cannot be tracked and context dependency injection
[英]EF Core Data Context injection across Projects
我有一個項目 A,它是一個 class 庫和項目 B,它使用 A。項目 A 是一個可以跨項目(例如 B)使用的通用幫助程序庫。
EF Core 數據上下文和數據實體需要在項目 B 中定義(因為它們可能因項目而異),但我需要將數據上下文注入到項目 A 中服務類的構造函數中(以通用方式處理所有內容)。 在 Project BI 中有數據上下文
public class MyDataContext : DbContext
{
public MyDataContext(DbContextOptions<MyDataContext> options): base(options)
{
}
public DbSet<Test> Tests { get; set; }
}
在項目 AI 中有實現 IUnitOfWork 的 class UnitOfWork。 在它的構造函數中,我需要注入數據上下文。 但是,由於項目 A 不能引用項目 B(項目 A 是通用的),我不能在參數列表中使用數據上下文的實際名稱。 由於datacontext繼承自DbContext,我試過了
public UnitOfWork(DbContext dc){...}
在項目 B 的啟動中,我有
services.AddDbContext<MyDataContext>(options =>
{
options.UseSqlServer("...<the connection string> ...");
});
services.AddScoped<IUnitOfWork, UnitOfWork>();
一切都可以編譯,但在運行時需要創建 UnitOfWork 時,出現錯誤
System.AggregateException: Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: IUnitOfWork Lifetime: Scoped ImplementationType: UnitOfWork': Unable to resolve service for type 'Microsoft.EntityFrameworkCore.DbContext' while attempting to activate 'UnitOfWork'.)
內部例外是
InvalidOperationException: Unable to resolve service for type 'Microsoft.EntityFrameworkCore.DbContext' while attempting to activate 'UnitOfWork'.
任何幫助都深表感謝。
編輯我被要求在評論中提供 UnitOfWork class 詳細信息。 所以這里
public class UnitOfWork : IUnitOfWork
{
private readonly DbContext dc;
private readonly IServiceProvider serviceProvider;
public UnitOfWork(DbContext dc, IServiceProvider serviceProvider)
{
this.dc = dc;
this.serviceProvider = serviceProvider;
}
public void BeginTransaction()
{
dc.Database.BeginTransaction();
}
public void BeginTransaction(IsolationLevel isolationLevel)
{
dc.Database.BeginTransaction(isolationLevel);
}
public void CommitTransaction()
{
dc.Database.CommitTransaction();
}
public void RollbackTransaction()
{
dc.Database.RollbackTransaction();
}
public bool IsTransactionActive()
{
return dc.Database.CurrentTransaction != null;
}
public async Task<bool> SaveAsync()
{
return await dc.SaveChangesAsync() > 0;
}
public bool Save()
{
return dc.SaveChanges() > 0;
}
}
您的UnitOfWork
服務依賴於DbContext
類型,而不是注冊到 DI 的派生MyDataContext
類型。 所以你有兩個選擇:
您可以像這樣修改 UnitOfWork 注冊(告訴 IoC 容器使用 MyDataContext 實例化 UnitOfWork):
services.AddScoped<IUnitOfWork>(srp => new UnitOfWork(srp.GetRequiredService<MyDataContext>(), srp));
或者您也可以將DbContext
注冊到 DI 中,因此 DI 容器知道當有人請求 DbContext 時它應該返回 MyDbContext:
services.AddScoped<DbContext, MyDataContext>();
請注意,您的UnitOfWork
class 中似乎未使用ServiceProvider
字段。
解決方案是進行兩項更改。 首先是按照@fbede 的建議顯式注冊服務
services.AddScoped<DbContext, MyDataContext>();
現在,當我們這樣做時,我們失去了通過AddDbContext
Extension 方法設置DbContextOptionsBuilder
選項的便利性。
所以我們需要重寫datacontext中的OnConfiguring
方法來設置我們需要的配置選項。 例如:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(configuration.GetConnectionString(<key>));
}
當然, IConfiguration
是在MyDataContext
構造函數中注入的
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.