0
我有一個空的DbContext。映射是動態創建的,而DbContext通常使用Set();對不同的模型使用相同的dbcontext
以下是我的通用DbContext。
/// <summary>
/// Object context
/// </summary>
public class MethodObjectContext : DbContext, IDbContext
{
private readonly IEventPublisher _eventPublisher;
public MethodObjectContext(string nameOrConnectionString, IEventPublisher eventPublisher)
: base(nameOrConnectionString)
{
_eventPublisher = eventPublisher;
}
public MethodObjectContext(DbConnection existingConnection, bool contextOwnsConnection, IEventPublisher eventPublisher)
: base(existingConnection, contextOwnsConnection)
{
_eventPublisher = eventPublisher;
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
_eventPublisher.Publish(new ModelCreating(modelBuilder));
base.OnModelCreating(modelBuilder);
}
public new IDbSet<TEntity> Set<TEntity>() where TEntity : class
{
return base.Set<TEntity>();
}
}
我試圖寫一個單元測試,將斷言該數據庫是不同步的,如果我改變映射(從ModelCreating事件)。
以下是我的測試代碼。
[TestClass]
public class MigrationTests
{
private string _connectionString = string.Empty;
private string _testDb = string.Empty;
public MigrationTests()
{
_testDb = Path.Combine("C:\\", System.Reflection.Assembly.GetExecutingAssembly().GetName().Name.Replace(".", "") + ".sdf");
if (File.Exists(_testDb))
File.Delete(_testDb);
_connectionString = string.Format("Data Source={0};Persist Security Info=False;", _testDb);
Database.DefaultConnectionFactory = new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0");
}
[TestMethod]
public void ThrowsErrorForOutOfDateDatabase()
{
// The initializer will handle migrating the database.
// If ctor param is false, auto migration is off and an error will be throw saying the database is out of date.
Database.SetInitializer(new MigrationDatabaseInitializer<MethodObjectContext>(false));
// Create the initial database and do a query.
// This will create the database with the conventions of the Product1 type.
TryQueryType<Product1>("Product");
// The next query will create a new model that has conventions for the product2 type.
// It has an additional property which makes the database (created from previous query) out of date.
// An error should be thrown indicating that the database is out of sync.
ExceptionAssert.Throws<InvalidOperationException>(() => TryQueryType<Product2>("Product"));
}
private void TryQueryType<T>(string tableName) where T : class
{
using (var context = new MethodObjectContext(_connectionString, new FakeEventPublisher(x => x.ModelBuilder.Entity<T>().ToTable(tableName))))
{
var respository = new EfRepository<T>(context);
var items = respository.Table.ToList();
}
}
}
我的Product1類是一個POCO對象,而我的Product2類是具有額外的db字段的同一個對象。
我的問題是,當我new()第二次Method.comContext並做一個查詢,ModelCreating方法不會被調用,導致我得到以下錯誤。
The entity type Product2 is not part of the model for the current context.
Product2將被調用的ModelCreating事件的上下文的一部分,但事實並非如此。有任何想法嗎?
注意:由於我們使用相同的連接字符串(sdf),並且創建的數據庫未創建第二個調用(Product2)所需的附加字段,所以我期待錯誤。
請注意,緩存是有原因的。構建模型可能很昂貴,如果每次使用上下文時都會執行該模型,那麼應用程序可能會出現性能問題。更好的方法是直接使用DbModelBuilder創建DbCompiledModels,然後根據需要進行緩存。 DbContext具有接受DbCompiledModel的構造函數。 – 2012-04-07 23:02:17