【发布时间】:2014-01-29 06:01:43
【问题描述】:
我正在用 EF6 和 aspnet Identity 构建一个项目。
我面临以下问题:
如果我打电话
var account = await FindByNameAsync(userName); // account.IsConfirmed = true
我得到了我正在寻找的帐户(例如:isConfirmed = true)。
当我手动更改数据库中的值 (isConfirmed = true -> isConfirmed = false) 并再次运行查询时,我仍然得到旧帐户对象 (isConfirmed = true)
var account = await FindByNameAsync(userName); // Should be account.IsConfirmed = false, but still gives me IsConfirmed = true
我尝试在我的 DbContext 构造函数中添加以下内容
> this.Configuration.ProxyCreationEnabled = false;
> this.Configuration.LazyLoadingEnabled = false;
但这并没有改变任何东西。
对此我能做些什么?缓存的数据会保留多长时间? 我看到的所有帖子都要求您运行查询(从 .. in ..),但是看到我如何使用 aspnet Identity 而我无法控制这些事情,我该怎么办?
谢谢!
编辑:添加 dbContext 信息
我的 IoC(统一)
container.RegisterType<IUnitOfWork, UserManagementContext>(new HttpContextLifetimeManager<IUnitOfWork>());
container.RegisterType<IUserStore<Account>, UserStore<Account>>(new InjectionConstructor(container.Resolve<IUnitOfWork>()));
HttpContextLifeTimeManager:
public class HttpContextLifetimeManager<T> : LifetimeManager, IDisposable
{
public override object GetValue()
{
return HttpContext.Current.Items[typeof(T).AssemblyQualifiedName];
}
public override void SetValue(object newValue)
{
HttpContext.Current.Items[typeof(T).AssemblyQualifiedName] = newValue;
}
public override void RemoveValue()
{
HttpContext.Current.Items.Remove(typeof(T).AssemblyQualifiedName);
}
public void Dispose()
{
RemoveValue();
}
}
我的工作单位
public interface IUnitOfWork : IDisposable
{
void Save();
Task SaveAsync();
DbSet<TEntity> EntitySet<TEntity>() where TEntity : class;
void MarkAsModified<TEntity>(TEntity entity) where TEntity : class;
}
我的用户管理上下文
public class UserManagementContext : IdentityDbContext<Account>, IUnitOfWork
{
static UserManagementContext()
{
//Database.SetInitializer<UserManagementContext>(new RecreateDatabase());
Database.SetInitializer<UserManagementContext>(null);
}
public UserManagementContext()
: base("Name=UserManagementConnection")
{
this.Configuration.ProxyCreationEnabled = false;
this.Configuration.LazyLoadingEnabled = false;
}
// ... (my Dbsets)
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// configuration ..
}
public void Save()
{
SaveChanges();
}
public async Task SaveAsync()
{
await SaveChangesAsync();
}
public DbSet<TEntity> EntitySet<TEntity>() where TEntity : class
{
return this.Set<TEntity>();
}
public void MarkAsModified<TEntity>(TEntity entity) where TEntity : class
{
this.Entry(entity).State = EntityState.Modified;
}
}
更新:
我发现了另一个奇怪的事情。当我设置我的上次登录日期字段时,该更改被拾取,但是当我设置我的 isConfirmed 字段时,该更改不会被拾取..(数据库更改实际上被缓存的数据覆盖!
因此,这确认了通过代码输入的数据得到了持久化,但数据库中的手动更改被忽略了。
更新 2 万一有人也有这个问题:问题不是 aspnet Identity,而是 EF。
我所做的是实现自己的用户存储并手动访问 EF 并使用 .AsNoTracking() 来避免缓存。
【问题讨论】:
-
您的 FindByNameAsync 看起来如何?
-
@AkashKava 这是一个来自 aspnet 身份的函数 (=> UserManager
) -
您是每个请求使用一个实例,还是为整个应用程序使用一个 DbContext 实例? DbSet 的 Find 方法将值缓存在本地对象中,除非您明确清除它。这是实体框架的问题。
-
我在一个请求 (MVC) 的生命周期中使用一个 dbContext
-
你能发布一些代码吗?您必须知道 HttpContext 和一些缓存成员不能很好地与异步代码一起使用,因为多个异步方法在同一线程上执行。
标签: c# .net entity-framework caching asp.net-identity