在DbContext

时间:2016-06-23 20:08:16

标签: entity-framework ef-code-first dbcontext

我正在尝试使用EF迁移来构建/播种我的数据库,但是当我使用update-database命令时,我的DbContext导致错误。

我实现的DbContext有两个构造函数:一个不接受参数,另一个接受IUserContext接口。 IUserContext接口返回用户名作为字符串。 IUserContext用于SaveChanges()方法,用于设置我所有实体共有的用户相关审计字段(例如CreatedBy,UpdatedBy)。根据IUserContext接口的实现,可以从HttpContext(在mvc应用程序中),WindowsIdentity(在控制台应用程序中)等中检索用户名。

如果用户尝试在DbContext上调用SaveChanges并且未设置IUserContext,则会抛出异常。基本上, 如果IUserContext接口无法提供用户名以便记录谁正在进行修改,我不希望保存在DbContext中的更改。 如果DbContext正在仅用于查询,使用no-args构造函数不是问题,因为IUserContext仅在SaveChanges期间使用。

当我尝试使用update-database命令时,DbMigrationsConfiguration被赋予一个使用no-args构造函数实例化的DbContext实例。因此,当它尝试在Seed()方法之后调用DbContext的SaveChanges时抛出异常。

问题: 如何将IUserContext传递给我的DbContext,这样update-database命令不会失败,更重要的是,能够将相应的实体字段设置为播种用户名的用户名更改? 我可以在DbMigrationsConfiguration中执行某种形式的DI或其他自定义吗?我应该简单地向DbContext添加一个IUserContext访问器方法,以便可以在构造函数之外设置IUserContext吗?

也许我应该问一个更大的问题: 将用户信息转发到DbContext的最佳(最通用?)方式是什么,以便记录谁在制作修改

我考虑过将这个逻辑移到我的应用程序的业务层,但将它封装在DbContext的SaveChanges中似乎很方便(更改跟踪时更是如此)已启用)。

1 个答案:

答案 0 :(得分:0)

我们有类似的情况,我们在SaveChanges()覆盖中记录修改后的用户。我们最终做的是创建一个BaseWrapper并使用IoC来填充它。第二部分是创建迁移将用于创建上下文的MigrationsContextFactory。该类与ApplicationDbContext位于同一文件夹中。

using System.Data.Entity.Infrastructure;

namespace MyApp.Data
{
    public class MigrationsContextFactory : IDbContextFactory<ApplicationDbContext>
    {
        public ApplicationDbContext Create()
        {
            return new ApplicationDbContext(new HttpContextBaseWrapper());
        }
    }
}

public class HttpContextBaseWrapper : IHttpContextBaseWrapper
{
    public string UserName
    {
        get
        {
            if (HttpContext.Current == null || HttpContext.Current.User == null)
                return string.Empty;
            return HttpContext.Current.User.Identity.Name;
        }
    }
}

https://marazt.wordpress.com/2015/01/09/entity-framework-dbcontext-idbcontextfactory-and-codefirst-migration-problem/