我想在我的dbcontext中覆盖我的覆盖SaveChanges()中的一些数据而不传递任何参数。有什么建议?我正在使用MVC4和Entity Framework Database-First。
public partial class Entities : DbContext
{
public override int SaveChanges()
{
// i want to get user info from MVC model but no need to pass any parameters when call SaveChanges()
var UserInfo = userInfo;
// Call the original SaveChanges(), which will save both the changes made and the audit records
return base.SaveChanges();
}
}
答案 0 :(得分:1)
此解决方案具有相当的可扩展性,但您必须修改存储库和控制器中的代码才能使用注入的依赖项,而不是使用new
创建新实例。
安装Ninject。在Visual Studio中,找到程序包管理器控制台并在其中运行Install-Package Ninject.MVC4 -dependencyVersion Highest
。
添加构造函数注入。修改控制器,以便在其构造函数中获取存储库的实例。修改您的存储库,以便它在其构造函数中获取实体上下文的实例。在私有字段中缓存依赖项。示例代码:
// In your controller:
public MyController(MyRepository repo)
{
this.repo = repo;
}
// In your repository:
public MyRepository(Entities context)
{
this.context = context;
}
// In your entities:
public Entities(UserInfo userInfo)
{
this.userInfo = userInfo;
}
添加UserInfo提供程序。我们需要告诉Ninject从哪里获取UserInfo。我们可以在这里使用提供者界面:
public class UserInfoProvider : Provider<UserInfo>
{
protected override UserInfo CreateInstance(IContext context)
{
UserInfo UserInfo = new UserInfo();
// Do some complex initialization here.
return userInfo;
}
}
添加绑定。我们需要告诉Ninject使用提供程序。我们还希望将UserInfo实例和实体上下文的生命周期绑定到MVC的请求周期。更新App_Start \ NinjectWebCommon.cs:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<Entities>()
.ToSelf()
.InRequestScope();
kernel.Bind<UserInfo>()
.ToProvider<UserInfoProvider>()
.InRequestScope();
}
运行您的应用。 Ninject应该使用您的构造函数并提供请求的依赖项。
有关详细信息,请访问Ninject Wiki。
这不需要修改您的存储库,但它使代码不易测试,并且以某种方式类似于反模式。如果您的控制器调用多线程代码,这将无法工作。
添加上下文类。
public class UserInfoContext : IDisposable
{
private static readonly ThreadLocal<UserInfo> UserInfos = new ThreadLocal<UserInfo>();
public static UserInfo Current
{
get
{
if (UserInfos == null)
{
throw new InvalidOperationException("UserInfoContext has not been set.");
}
return UserInfos.Value;
}
}
public static UserInfoContext Create(UserInfo userInfo)
{
if (userInfo == null)
{
throw new ArgumentNullException("userInfo");
}
if (UserInfos.Value != null)
{
throw new InvalidOperationException("UserInfoContext should not be nested.");
}
UserInfos.Value = userInfo;
return new UserInfoContext();
}
private UserInfoContext() { }
public void Dispose()
{
UserInfos.Value = null;
}
}
包装您的控制器代码。示例:
public ActionResult Index()
{
using (UserInfoContext.Create(myUserInfo))
{
// do stuff that calls your repositories
return View();
}
}
更新您的实体类。
public partial class Entities : DbContext
{
public override int SaveChanges()
{
var UserInfo = UserInfoContext.Current;
// Call the original SaveChanges(), which will save both the changes made and the audit records
return base.SaveChanges();
}
}