[英]How to use multiple contexts for single DB, without violating dependency injection
假設我有一個從數據庫加載一些實體的方法,對每個實體進行 API 調用,從第三方獲取令牌並保存它們。 API 調用至關重要,因此我們希望每個調用都立即登錄到數據庫。
所以我把context.SaveChanges
放在CriticalAPI
中,分別保存每個日志。
問題是這個SaveChanges
還保存了在Method()
中修改的Posts
實體。
我希望CriticalAPI
只保存日志,而不是其他對象。 一種方法是創建另一個上下文並在該方法中使用,但它違反了依賴注入,因為我應該在我的方法中實例化一個新的上下文。
實現此要求的正確方法是什么?
public void Method(){
var entities = context.Posts.Where(/* something */).ToList();
foreach (var entity in entities){
var result = CriticalAPI(entity.Id);
entity.Token = result;
}
context.SaveChanges();
}
public int CriticalAPI(int id){
var token = /* do something critical */
context.Logs.Add(new Log(){
entityId = id
});
context.SaveChanges();
return token;
}
您可以使用抽象工廠模式。 只需定義上下文工廠接口並注入工廠。 然后在需要創建新上下文實例的任何地方使用工廠:
interface IDbContextFactory {
DbContext CreateContext();
}
//...
public void Method() {
using (var context = contextFactory.CreateContext()) {
context.Posts.Where(/* something */)
.ForEach(entity => {
var result = CriticalAPI(entity.Id);
entity.Token = result;
});
context.SaveChanges();
}
}
public int CriticalAPI(int id) {
using (var context = contextFactory.CreateContext()) {
var token = /* do something critical */
context.Logs.Add(new Log(){
entityId = id
});
context.SaveChanges();
return token;
}
}
您可以在調用context.Posts
之后添加.AsNoTracking()
方法,並且實體不會跟蹤更改。
public void method(){
var entities = context.Posts
.AsNoTracking() // <---- add this Method here
.Where(/* something */).ToList();
foreach (var entity in entities){
var result = CriticalAPI(entity.Id);
entity.Token = result;
}
context.SaveChanges();
}
您也可以為日志創建一個完全獨立的 dbContext,然后設置並保存該上下文。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.