繁体   English   中英

实体框架6.2.0-DbContext自动保存哪个用户创建或更新了DbSet值

[英]Entity Framework 6.2.0 - DbContext that automatically saves which user created or updated a DbSet value

如标题所示,我们需要存储哪个用户更新或创建了特定值。 以前,我们只需要保存CreatedDateUpdatedDate 这很容易,我们所有的实体都从一个名为EntityBase的抽象基类继承,该抽象基类实现了具有这些值的接口IEntity 然后, DbContext SaveChanges被覆盖,并且如果特定实体实现了IEntity ,则根据EntityState.AddedEntityState.Modified设置值。

interface IEntity
{
    DateTime CreatedDate { get; set; }

    string CreatedBy { get; set; }

    DateTime UpdatedDate { get; set; }

    string UpdatedBy { get; set; }

}

public abstract class EntityBase<T1>: IEntity
{
    public T1 Id { get; set; }

    public virtual DateTime CreatedDate { get; set; }
    public virtual string CreatedBy { get; set; }
    public virtual DateTime UpdatedDate { get; set; }
    public virtual string UpdatedBy { get; set; }
}

但是,新的要求是,我们还需要保存进行更改的用户。 一个简单的解决方案是通过构造函数添加用户,而没有一个空的构造函数。 但是,在其他情况下使用迁移时,这证明是一个问题:

Database.SetInitializer(new MigrateDatabaseToLatestVersion<CatalogServiceContext, Configuration>());
var migrator = new DbMigrator(new Configuration());

目标上下文'CatalogService.Data.Context.CatalogServiceContext'是不可构造的。 添加默认构造函数或提供IDbContextFactory的实现。

public class CatalogServiceContext : DbContext
{

    private readonly string _currentUser;

    public CatalogServiceContext(string currentUser) : base("name=CatalogContext")
    {
        _currentUser = currentUser;
    }

    public override int SaveChanges()
    {
        var now = DateTime.Now;

        foreach (var changedEntity in ChangeTracker.Entries())
        {
            if (changedEntity.Entity is IEntity entity)
            {
                switch (changedEntity.State)
                {
                    case EntityState.Added:
                        entity.CreatedDate = now;
                        entity.CreatedBy = _currentUser;
                        entity.UpdatedDate = now;
                        entity.UpdatedBy = _currentUser;
                        break;

                    case EntityState.Modified:
                        Entry(entity).Property(x => x.CreatedDate).IsModified = false;
                        Entry(entity).Property(x => x.CreatedBy).IsModified = false;
                        entity.UpdatedDate = now;
                        entity.UpdatedBy = _currentUser;
                        break;
                }
            }
        }

        return base.SaveChanges();
    }
}

我尝试实现IDbContextFactory但是它有一个类似的问题。

上下文工厂类型'CatalogService.Data.Context.CatalogServiceContextFactory'没有公共的无参数构造函数。 添加公共无参数构造函数,在上下文程序集中创建IDbContextFactory实现,或使用DbConfiguration注册上下文工厂。

public class CatalogServiceContextFactory : IDbContextFactory<CatalogServiceContext>
{
    private readonly string _currentUser;

    public CatalogServiceContextFactory(string currentUser)
    {
        _currentUser = currentUser;
    }

    public CatalogServiceContext Create()
    {
        return new CatalogServiceContext(_currentUser);
    }
}

解决方法是EntityBase中的两个方法,每次更新或创建值时都需要调用此方法。 这可行,但是我认为最好的解决方案仍然是构造函数中的强制用户。 还有其他人有类似的需求可以解决吗? 我想在DbContext解决它,而不是对每个DbSet使用存储库抽象。

public virtual EntityBase<T1> SetCreateFields(string currentUser)
{
    CreatedBy = currentUser;
    UpdatedBy = currentUser;
    return this;
}

public virtual EntityBase<T1> SetUpdateFields(string currentUser)
{
    UpdatedBy = currentUser;
    return this;
}

决定像这样解决它:

public class CatalogServiceContext : DbContext
{
    public ICurrentUser CurrentUser;

    [Obsolete("Use CatalogServiceContextUserWrapper instead")]
    public CatalogServiceContext() : base("name=CatalogContext")
    {

    }

    ...


public class CatalogServiceContextUserWrapper
{
    public CatalogServiceContext Context;

    public CatalogServiceContextUserWrapper(CatalogServiceContext context, ICurrentUser currentUser)
    {
        context.CurrentUser = currentUser;
        this.Context = context;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM