我正在使用EF4.1和MVC3,我需要一个覆盖来防止EF创建一个db(如果它不存在)。我想捕获错误并报告连接字符串中的初始目录(数据库名称)无效,而不是创建新的数据库。
但是,在开发期间,我希望允许对新类/属性进行更新,以根据数据库中的表/列创建。
这里有最佳实践或模式吗?
答案 0 :(得分:3)
在我的应用程序中,我完全禁用上下文初始化程序并手动处理数据库映射和架构。
例如:
public class AppDbContext : DbContext
{
public IDbSet<Account> Accounts { get; set; }
public AppDbContext() : base("connection_string")
{
Database.SetInitializer<AppDbContext>(null); // Important! Dont use entity framework initializer !important
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
/* Register custom mapping class */
modelBuilder.Configurations.Add(new AccountMapper());
base.OnModelCreating(modelBuilder);
}
}
自定义映射:
public class AccountMapper : EntityTypeConfiguration<Account>
{
/// <summary>
/// Employee entity mapper
/// </summary>
public AccountMapper()
{
ToTable("accounts");
HasKey(x => x.Id);
...
}
}
答案 1 :(得分:1)
我建议查看EF数据库初始化程序,特别是IDatabaseInitializer
接口。
如果您只是希望它在不存在时停止创建数据库,那么只需将初始化程序设置为null
即可。但是,如果您想记录这些事件或其他内容,那么只需创建自己的IDatabaseInitializer
- 这并不难。
然后您可以在global.asax.cs中设置初始值设定项Application_Start
,如下所示:
Database.SetInitializer(new YourCustomInitializer());
作为奖励,这是我用来运行数据库迁移的示例IDatabaseInitializer
(使用FluentMigrator)...如果我自己这么说的话,这非常方便!
public class MigrationsDbContextInitializer : IDatabaseInitializer<YourDbContext>
{
private static readonly ILog Logger = LogManager.GetLogger(typeof(MigrationsDbContextInitializer));
public void InitializeDatabase(YourDbContext context)
{
var announcer = new BaseAnnouncer(x => Logger.Info(x));
var runnerContext = new RunnerContext(announcer)
{
Database = "sqlserver2008",
Connection = context.Database.Connection.ConnectionString,
Target = "YourEntitiesNamespace",
PreviewOnly = false,
Task = "migrate"
};
new TaskExecutor(runnerContext).Execute();
}
}