我有基本的 Web Api 2 应用程序,其中包含业务逻辑和数据层。 UnitOfWork 封装 DBContext 。
我的UnitOfWok:
public class UnitOfWork : IUnitOfWork
{
public KnowBaseDBContext context { get; set; } = new KnowBaseDBContext();
public int Save()
{
var res = context.SaveChanges();
return res;
}
public void AttachToContext<T>(T obj) where T : class
{
var dbset = context.Set<T>();
dbset.Attach(obj);
}
// dispose()
}
我还使用 Unity容器和 Unity容器的 config 实现了依赖注入 的UnitOfWork :
container.RegisterType<IUnitOfWork, UnitOfWork>(new HierarchicalLifetimeManager(),
new InjectionConstructor());
我想要做的是在 ActionFilter.OnActionExecuted 中调用 UnitOfWork.Save():
public sealed class CommitOnSuccess : System.Web.Http.Filters.ActionFilterAttribute
{
private IUnitOfWork unitOfWork { get; set; }
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
if (actionExecutedContext.Exception == null)
{
unitOfWork = UnityConfig.GetConfiguredContainer().Resolve<IUnitOfWork>();
unitOfWork.Save();
}
base.OnActionExecuted(actionExecutedContext);
}
}
但是从我看到的 Unity容器在 Action 的 context 中工作(不知道它是如何工作的)所以我无法在 ActionFilter 中获得适当的上下文,因此无法在我的数据库中保存更改。如何以正确的方式 SaveChanges ?
我如何使用 UbitOfWork (不用担心,会受到反对):
private void UpdateSecondarySkills(Vacancy v, ICollection<int> skills)
{
var old_secondary_skills = v.TechSkills;
var ids = old_secondary_skills.Select(c => c.Id).ToList();
foreach (var skill in old_secondary_skills.ToList())
{
if (!skills.Contains(skill.Id))
{
v.TechSkills.Remove(skill);
}
}
if (v != null)
{
foreach (var skill in skills)
{
if (!ids.Contains(skill))
{
var existing_skill = new TechSkill { Id = skill };
unitOfWork.AttachToContext<TechSkill>(existing_skill);
v.TechSkills.Add(existing_skill);
}
}
}
}
答案 0 :(得分:1)
修改你的global.asax
添加这些事件处理程序
protected void Application_BeginRequest() { CurrentContext = new YourDbcontext; }
protected void Application_EndRequest()
{
if (CurrentContext != null)
CurrentContext .Dispose();
}
将此属性添加到global.asax
private const string ContextKey = "current.session";
public static YourDbContext CurrentContext
{
get { return (ISession) HttpContext.Current.Items[ContextKey]; }
private set { HttpContext.Current.Items[ContextKey] = value; }
}
现在,您需要设置容器以在解析上下文时调用CurrentContext属性。我不知道Unity是如何做到的。我使用Castle Windsor,你就这样注册了
container
.Register(Component.For<DbContext>().UsingFactoryMethod(() => MvcApplication.CurrentContext)
.LifeStyle
.PerWebRequest);
您可以这样做
container.Register(Classes.FromAssemblyContaining<YourDbContext>()
.BasedOn<DbContext>()
.LifeStyle
.PerWebRequest);
但我没试过。
然后只要您通过容器解析ApiControllers,只需在构造函数中传递YouDbContext。
现在,您应该根据每个Web请求按用户解析上下文。
答案 1 :(得分:0)
您是否在项目内的任何位置UnitOfWork
使用了DBContext
上的数据库内容。如果不是UnitOfWork
可能有另一个DBContext
,那么它看不到任何更改,因此它不会保存任何
也许你需要看看这个thread