[英]Injected Transient service still tracks entities in ChangeTracker in DbContext
當我插入一個實體時,直接在之后,嘗試更新同一個實體,如下所示:
var insertedTransferId = await _transferDs.Create_Async(transferObject);
//update transfer key
if (insertedTransferId > 0)
{
transferObject.TransferKey = $"{transferObject.TransferKey}00{insertedTransferId}";
return await _transferDs.Update_Async(transferObject, true);
}
_transferDS Create_Async(TransferModel 模型)
public async Task<int> Create_Async(TransferModel model)
{
try
{
var entity = _mapper.Map<Transfer>(model);
this._repo.Create<Transfer>(entity);
this._repo.Context.Entry(entity).Reference(nameof(entity.TransferMeta)).IsModified = false;
var success = await _repo.SaveAsync() > 0 ? true : false;
if (success)
await this.UpdateTransferByTransferId(entity.TransferId);
return success ? entity.TransferId : 0;
}
catch
{
throw;
}
}
_repo.Create(實體)
public virtual void Create<TEntity>(TEntity entity)
where TEntity : class
{
Context.Set<TEntity>().Add(entity);
}
我遇到以下問題:
無法跟蹤實體類型“Transfer”的實例,因為已在跟蹤具有相同鍵值的另一個實例
在初始插入之后, EntityState
被Added
。 當我更新實體時,它抱怨實體已被跟蹤。
我想,在.Net Core DI() 的幫助下,我可以使用Transient
的Lifetime
scope 注入我的上下文、服務等,這意味着,每當我請求我的上下文時,都會提供一個新實例,並且ChangeTracker
將是干凈的。 不是這樣。
您可以在下面看到,我正在設置上下文的生命周期以及服務:
//Database context and repository
services.AddDbContext<IMyContext, MyContext>(builder =>
{
builder.UseSqlServer(connectionString: Configuration.GetConnectionString("myConnection"), sqlServerOptionsAction: null);
builder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
//builder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
builder.EnableSensitiveDataLogging(true);
}, ServiceLifetime.Transient);
services.AddTransient<IRepo, Repo>();
我錯過了什么,或者不理解什么?
從文檔:
短暫的
每次從服務容器請求它們時,都會創建瞬態生命周期服務 (AddTransient)。 這個生命周期最適合輕量級、無狀態的服務。
因此Create_Async
和Update_Async
方法調用是在_transferDs
的同一個實例上調用的,該實例將具有您的數據庫上下文的相同實例,導致_transferDs
只需解析MyContext
一次。
要檢查它,您可以嘗試將MyContext
注入Repo
兩次並在Create
和Update
上調用不同的(盡管不要在實際/生產代碼中執行此操作)。
UPD
我如何每次都強制一個新實例?
我認為您不應該,您可以檢查實體是否已被跟蹤或使用Find
,但如果您堅持 - 您可以注冊“工廠”(除了普通注冊)並解決它:
services.AddTransient<Func<IRepo>>(s => () => s.GetRequiredService<IRepo>());
Func<IRepo> repoFactory
注入您的類並使用它代替_repo
:
var repo = _repoFactory();
repo.Create<Transfer>(entity);
repo.Context.Entry(entity).Reference(nameof(entity.TransferMeta)).IsModified = false;
var success = await repo.SaveAsync() > 0 ? true : false;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.