[英]Inject ChangeTracker into constructor
我想重用我們在另一個使用asp.net核心的項目中建立的概念。 在使用以下代碼保存實體之前, DbContext
將調用已注冊的IEntityMetadataProvider
:
public class SppdContext : DbContext
{
private readonly IEnumerable<IEntityMetadataProvider> _entityMetadataProviders;
public SppdContext(DbContextOptions<SppdContext> options, IEnumerable<IEntityMetadataProvider> entityMetadataProviders) : base(options)
{
_entityMetadataProviders = entityMetadataProviders;
}
public override int SaveChanges()
{
PrepareSaveChanges();
return base.SaveChanges();
}
private void PrepareSaveChanges()
{
ChangeTracker.DetectChanges();
SetModifierMetadataOnChangedEntities();
}
private void SetModifierMetadataOnChangedEntities()
{
foreach (var entityMetadataProvider in _entityMetadataProviders)
{
entityMetadataProvider.SetModifierMetadataOnChangedEntities();
}
}
}
-
public class EntityMetadataProvider : IEntityMetadataProvider
{
private readonly ChangeTracker _changeTracker;
public EntityMetadataProvider(ChangeTracker changeTracker)
{
_changeTracker = changeTracker;
}
public void SetModifierMetadataOnChangedEntities()
{
var entriesToSetModifier = _changeTracker.Entries<BaseEntity>().Where(e => HasToSetModifierMetadata(e.State)).ToList();
if (entriesToSetModifier.Count > 0)
{
var saveDate = DateTime.UtcNow;
foreach (var entryToSetModifier in entriesToSetModifier)
{
SetModifierMetadataProperties(entryToSetModifier, saveDate);
}
}
}
private static bool HasToSetModifierMetadata(EntityState state)
{
return state == EntityState.Added || state == EntityState.Modified;
}
private static void SetModifierMetadataProperties(EntityEntry<BaseEntity> entry, DateTime saveDate)
{
if (entry.State == EntityState.Added)
{
entry.Property(e => e.CreatedOn).CurrentValue = saveDate;
}
else
{
entry.Property(e => e.CreatedOn).IsModified = false;
}
}
}
DbContext
正在這樣注冊:
var connectionString = "Data Source=.\\SQLEXPRESS; Initial Catalog=Sppd; Integrated Security=true; MultipleActiveResultSets=True;";
services.AddDbContext<SppdContext>(options => options.UseSqlServer(connectionString));
通過這種實現,當在var context = serviceScope.ServiceProvider.GetRequiredService<SppdContext>();
上時,我得到以下異常var context = serviceScope.ServiceProvider.GetRequiredService<SppdContext>();
:
Unable to resolve service for type 'Microsoft.EntityFrameworkCore.ChangeTracking.ChangeTracker' while attempting to activate 'SppdDocs.Infrastructure.DbAccess.EntityMetadataProvider'.
如何注冊ChangeTracker
以便可以注入?
如果我理解正確,則想在SppdContext的更改跟蹤器中查找更改。
您不能通過注入獲得changetracker。 它由您的上下文實例擁有。 調用方法而不是構造函數時,應傳遞Changetracker。
在SpddContext類中,您將獲得
private void SetModifierMetadataOnChangedEntities()
{
foreach (var entityMetadataProvider in _entityMetadataProviders)
{
entityMetadataProvider.SetModifierMetadataOnChangedEntities(ChangeTracker);
}
}
並在EntityMetaDataProvider中:
public class EntityMetadataProvider : IEntityMetadataProvider
{
public EntityMetadataProvider()
{
}
public void SetModifierMetadataOnChangedEntities(ChangeTracker changeTracker)
{
var entriesToSetModifier = changeTracker.Entries<BaseEntity>().Where(e =>
HasToSetModifierMetadata(e.State)).ToList();
if (entriesToSetModifier.Count > 0)
{
var saveDate = DateTime.UtcNow;
foreach (var entryToSetModifier in entriesToSetModifier)
{
SetModifierMetadataProperties(entryToSetModifier, saveDate);
}
}
}
...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.