我正在使用EF和DB First Approach构建ASP.NET MVC3网站。我需要为用户提供一个可靠的运行时数据库上下文切换机制。我有几个用于远程“研讨会”的数据库(相同的模式),公司总部的应用程序用户需要能够随时在数据库之间切换。
首先,我实现了一个具有ChangeDbContext(字符串dbname)的基本控制器。它将选定的dbName持久保存到Session,然后我在OnActionExecuting方法中从Session中检索。然而事实证明它不可靠,因为会话行为不可预测(随机过期等)所以我正在寻找一种聪明的方法来用其他东西替换Session。
我可以使用以下建议: - 在哪里放置EntityFramework对象初始化(BaseController Constructor?) - 对于使用WindowsAuth进行数据库连接的模拟,我应该做哪些其他更改?
答案 0 :(得分:2)
首先,您需要确保您的应用程序会话可以在重新启动和应用程序池循环后继续运行。 See this
其次,您需要根据经过身份验证的用户请求为您的DBContext注入连接字符串。
我假设您拥有一个充满用户的数据库,因此您需要做的是在SQL表中保存可能的连接字符串列表,并将它们与相关的用户帐户相关联。对用户进行身份验证后,您需要检索与用户帐户关联的连接字符串。 您不希望将连接字符串存储在会话或任何其他可能将敏感数据暴露给Web客户端的机制中。总而言之,您需要做什么。
将字符串注入实体很容易。
如果您首先使用EF 4.1代码,那么您的DBContext将如下所示。 EF 4.1接受普通的ADO.NET连接字符串。
public class ExampleProvider : DbContext, IExampleProvider
{
private readonly string _nameOrStringConnection;
public ExampleProvider()
{
}
public ExampleProvider(string nameOrStringConnection)
: base(nameOrStringConnection)
{
_nameOrStringConnection = nameOrStringConnection;
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Example>().ToTable("example");
modelBuilder.Entity<Example>().HasKey(x => x.ExampleId);
}
public DbSet<Example> Examples { get; set; }
}
如果您正在使用EF.edmx,则需要确保注入的连接字符串包含edmx元数据文件信息,如此...
...“元数据= RES:// /ExampleModel.csdl|res:// /ExampleModel.ssdl | RES://*/ExampleModel.msl; ...
如果你查看edmx设计器文件,你会看到你的DBContext有几个构造函数重载。根据您的需要使用第二次或第三次超载。
#region Contexts
/// <summary>
/// No Metadata Documentation available.
/// </summary>
public partial class Entities : ObjectContext
{
#region Constructors
/// <summary>
/// Initializes a new Entities object using the connection string found in the 'Entities' section of the application configuration file.
/// </summary>
public Entities() : base("name=Entities", "Entities")
{
this.ContextOptions.LazyLoadingEnabled = true;
OnContextCreated();
}
/// <summary>
/// Initialize a new Entities object.
/// </summary>
public Entities(string connectionString) : base(connectionString, "Entities")
{
this.ContextOptions.LazyLoadingEnabled = true;
OnContextCreated();
}
/// <summary>
/// Initialize a new Entities object.
/// </summary>
public Entities(EntityConnection connection) : base(connection, "Entities")
{
this.ContextOptions.LazyLoadingEnabled = true;
OnContextCreated();
}
#endregion
/// incomplete file
祝你好运!
答案 1 :(得分:1)
Cookie可以持续很长时间,比会话长得多。您还可以查看隐藏的页面变量或损坏的URL。
答案 2 :(得分:0)
1)会话不会在randomply到期...但是在你设置we.config之后...默认是10分钟。 Seesion必须过期,因为没有办法知道用户离开我们的网站...所以如果他们停止访问页面,比如10分钟,我们ASSUME,他们就离开了...你可以增加这个时间,但问题仍然存在。 2)Tou可以直接将信息存储在cookie中。现在因为cookie只会浪费浏览器上的资源(非常小的空间),所以你可以使cookie保持不变......这样它永远不会过期 3)作为cookie的替代,您可以将此信息与用户的凭证信息(登录名等)一起存储。您可以使用配置文件提供程序来定义属性DBChosen。