回答

8

当EF需要第一次访问数据库(所以它不在上下文实例期间)时调用此方法。如果数据库不存在,它使用来自编译模型的信息来创建它。该模型每个应用程序只创建一次(它在内部被缓存),所以即使您处理上下文,您的模型仍将在下一个实例中重用。

-2

当EF4创建数据库时,OnModel创建触发器。通常这个事件被用来配置EF4生成数据库的方式,所以如果你以前执行过你的应用程序,并且你的模型保持不变,那么数据库已经存在,EF4也不会尝试生成一个新的(尽管这种行为也取决于一些配置参数)。

+0

是不是这个配置应该始终执行即使在我的情况下(数据库不会在模型更改时生成)?否则EF如何知道如何映射列? – rovsen 2011-04-12 11:54:12

+0

如果未生成数据库,则不会触发OnModelCreating。在codefirst方式中,EF对所有未指定的映射使用约定。一旦创建了数据库,EF每次执行应用程序时都会记住映射。如果在开发应用程序时在模型中进行更改,也许应该使用“AlwaysRecreateDatabase”选项,每次运行应用程序时都会重新生成数据库,并且OnModelCreating将始终触发。 – 2011-04-13 09:08:39

30

要清楚的是,OnModelCreating与EF是否为您创建数据库无关。

为了与数据库进行交互,实体框架必须建立一个将被持久化的实体模型。如果它尚未建立并缓存该模型,则会触发此事件。

构建模型后,由它生成的哈希,和EF然后尝试连接到数据库,看是否(一)存在,(B),它包含的版本信息,存储在前面的哈希EdmMetadata表,以及(c)该散列是否与之前根据模型计算出的散列匹配。

如果散列值不匹配,则EF使用已设置的数据库初始值设定项(通过调用Database.SetInitializer(new SomeInitializerType()),这可能会或可能不会删除,创建或以其他方式修改数据库。默认的初始化器,当你没有指定一个不同的初始化器时,对你的数据库没有任何作用,一旦它运行,实体框架将拒绝与数据库交互,如果它不同步。

如果你的数据库不包含一个带有散列的EdmMetadata表,Entity Framework假定你正在自己管理数据库模式,并且乐于尝试使用它,希望你已经把事情做好了。如果该模式与以后的EF期望不符,则在调用SaveChanges()等时会出现错误。

在所有这些场景中,无论您是管理自己的数据库模式还是让EF根据需要进行删除和重新创建,数据库是否与您的模型同步,OnModelCreating事件首次触发Entity Framework需要知道它的持续性。