我正在使用多租户应用程序,该应用程序使用具有多个客户数据库且具有共享DbContext的相同Web应用程序。当用户根据其凭据登录时,我向DbContext提供连接字符串并加载数据。当多个用户同时登录时会出现问题,并且当DbContext继续在不同用户之间切换时,他们可以看到彼此的数据。
我主要使用EF 5.0和Autofac IOC。什么是管理这个的最好方法?
如何让我的DbContext为该特定用户维护其数据,即使其他用户登录并且它们具有不同的数据库上下文,也不会更改?
这是我的登录页面中的代码,
protected void LoginBtn_Click(object sender, EventArgs e)
{
int i = Convert.ToInt32(CustomerId.Text);
var builder = new ContainerBuilder();
var profile = _profileProvider.GetCustomerProfile(i);
ConnectionStringManager.ConnectionString = profile.connString;
builder.RegisterModule<CustomerDataModule>();
builder.Update(_container);
Response.Redirect("Home.aspx");
}
这是我的静态变量,它给出了连接字符串
public static class ConnectionStringManager
{
public static string ConnectionString { get; set; }
}
这是我的模块,它包含所有实体和上下文类,
public class CustomerDataModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.Register(c =>
{
ConnectionString = ConnectionStringManager.ConnectionString;
return new CustomerDataContext(ConnectionString);
})
.As<ICustomerDataContext>()
.As<IDbContext>()
.InstancePerDependency();
builder.RegisterType<CustomerDataContextFactory>().As<ICustomerDataContextFactory>();
var assembly = Assembly.GetExecutingAssembly();
builder.RegisterAssemblyTypes(assembly)
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces()
.InstancePerDependency();
}
}
这是我的DbContext,
public partial class CustomerDataContext: DbContext, ICustomerDataContext
{
public CustomerDataContext(string connectionString)
: base(connectionString)
{ }
.......
这是我的一个存储库,
public class CustomerRepository : GenericRepository<Customer, int>, ICustomerRepository
{
public CustomerRepository(ICustomerDataContext context)
: base(context, customer => customer.Id)
{
}
}
答案 0 :(得分:2)
Web应用程序中的静态变量意味着同时在所有用户之间共享其数据。您需要将该值移动到会话变量,该变量特定于每个用户。
var builder = new ContainerBuilder();
// will add `HTTP request lifetime scoped` registrations (InstancePerHttpRequest) for the HTTP abstraction classes
builder.RegisterModule(new AutofacWebTypesModule());
builder.Register<MyType>(ctx =>
{
var sessionBase = ctx.Resolve<HttpSessionStateBase>();
//now use the session value to retrieve the connection string
});