2012-07-25 22 views
0

最近我減少了我的數據庫權限,因此我無法刪除並重新創建數據庫。這導致我使用nuget中的DontDropDbJustCreateTablesIfModelChanged數據庫初始化。如何在DontDropDbJustCreateTablesIfModelChanged後種子數據庫

但是我現在堅持要如何種子數據,因爲Seed函數不在初始化中,所以我不能重寫它。這是我希望能夠做到的。

public class MyDBInitialiser : DontDropDbJustCreateTablesIfModelChanged<MyContext> 
{ 
    protected override void Seed(MyContext context) 
    { 
     base.Seed(context); 

     context.Item.Add(new Item() { ItemId = 1, Name = "Item 1"}); 
     context.Item.Add(new Item() { ItemId = 2, Name = "Item 2"}); 
     context.Item.Add(new Item() { ItemId = 3, Name = "Item 3"}); 
    } 
} 

在這種情況下是否有另一種種子數據播種方式。

回答

0

我的項目我分裂從數據庫種子數據庫初始化。如果您使用控制反轉,你應該能夠做這樣的事情在你的作文根(的Application_Start如果你是從一個Web應用程序消耗的DbContext):

var seeder = ServiceLocatorPattern 
    .ServiceProviderLocator.Current.GetService<ISeedDb>(); 
if (seeder != null) seeder.Seed(); 

接口:

public interface ISeedDb, IDisposable 
{ 
    void Seed(); 
} 

一種可能實現:

public class MyDbSeeder : ISeedDb 
{ 
    private readonly MyContext _context; 

    public MyDbSeeder(MyContext context) 
    { 
     _context = context; 
    } 

    public void Seed() 
    { 
     _context.Item.Add(new Item { ItemId = 1, Name = "Item 1" }); 
     // ... etc 
    } 

    public void Dispose() 
    { 
     _context.Dispose(); 
    } 
} 
+0

謝謝,這是我渡過心理邊溝,以不同的方式思考這個問題。 – 2012-07-25 14:28:09

+0

沒問題。順便說一句,我在我的github帳戶中有幾個項目,可以幫助我在上面發佈的ServiceProviderLocator和ServiceProviderExtension方法。祝你好運。 – danludwig 2012-07-25 17:46:47

1

簡單,

public class DontDropDbJustCreateTablesIfModelChanged<T> 
        : IDatabaseInitializer<T> where T : DbContext 
{ 
    private EdmMetadata _edmMetaData; 

    public void InitializeDatabase(T context) 
    { 
     ObjectContext objectContext = 
       ((IObjectContextAdapter)context).ObjectContext; 

     string modelHash = GetModelHash(objectContext); 

     if (CompatibleWithModel(modelHash, context, objectContext)) 
      return; 

     DeleteExistingTables(objectContext); 
     CreateTables(objectContext); 

     SaveModelHashToDatabase(context, modelHash, objectContext); 
     Seed(context); 
    } 

    protected virtual void Seed(T context) { } 

    private void SaveModelHashToDatabase(T context, string modelHash, 
              ObjectContext objectContext) 
    { 
     if (_edmMetaData != null) objectContext.Detach(_edmMetaData); 

     _edmMetaData = new EdmMetadata(); 
     context.Set<EdmMetadata>().Add(_edmMetaData); 

     _edmMetaData.ModelHash = modelHash; 
     context.SaveChanges(); 
    } 

    private void CreateTables(ObjectContext objectContext) 
    { 
     string dataBaseCreateScript = 
      objectContext.CreateDatabaseScript(); 
     objectContext.ExecuteStoreCommand(dataBaseCreateScript); 
    } 

    private void DeleteExistingTables(ObjectContext objectContext) 
    { 
     objectContext.ExecuteStoreCommand(Dropallconstraintsscript); 
     objectContext.ExecuteStoreCommand(Deletealltablesscript); 
    } 

    private string GetModelHash(ObjectContext context) 
    { 
     var csdlXmlString = GetCsdlXmlString(context).ToString(); 
     return ComputeSha256Hash(csdlXmlString); 
    } 

    private bool CompatibleWithModel(string modelHash, DbContext context, 
             ObjectContext objectContext) 
    { 
     var isEdmMetaDataInStore = 
      objectContext.ExecuteStoreQuery<int>(LookupEdmMetaDataTable) 
      .FirstOrDefault(); 

     if (isEdmMetaDataInStore == 1) 
     { 
      _edmMetaData = context.Set<EdmMetadata>().FirstOrDefault(); 
      if (_edmMetaData != null) 
      { 
       return modelHash == _edmMetaData.ModelHash; 
      } 
     } 
     return false; 
    } 

    private string GetCsdlXmlString(ObjectContext context) 
    { 
     if (context != null) 
     { 
      var entityContainerList = context.MetadataWorkspace 
       .GetItems<EntityContainer>(DataSpace.SSpace); 

      if (entityContainerList != null) 
      { 
       var entityContainer = entityContainerList.FirstOrDefault(); 
       var generator = 
        new EntityModelSchemaGenerator(entityContainer); 
       var stringBuilder = new StringBuilder(); 
       var xmlWRiter = XmlWriter.Create(stringBuilder); 
       generator.GenerateMetadata(); 
       generator.WriteModelSchema(xmlWRiter); 
       xmlWRiter.Flush(); 
       return stringBuilder.ToString(); 
      } 
     } 
     return string.Empty; 
    } 

    private static string ComputeSha256Hash(string input) 
    { 
     byte[] buffer = new SHA256Managed() 
      .ComputeHash(Encoding.ASCII.GetBytes(input)); 

     var builder = new StringBuilder(buffer.Length * 2); 
     foreach (byte num in buffer) 
     { 
      builder.Append(num.ToString("X2", 
       CultureInfo.InvariantCulture)); 
     } 
     return builder.ToString(); 
    } 

    private const string Dropallconstraintsscript = 
     @"select 
     'ALTER TABLE ' + so.table_name + ' DROP CONSTRAINT ' 
     + so.constraint_name 
     from INFORMATION_SCHEMA.TABLE_CONSTRAINTS so"; 

    private const string Deletealltablesscript = 
     @"declare @cmd varchar(4000) 
     declare cmds cursor for 
     Select 
      'drop table [' + Table_Name + ']' 
     From 
      INFORMATION_SCHEMA.TABLES 

     open cmds 
     while 1=1 
     begin 
      fetch cmds into @cmd 
      if @@fetch_status != 0 break 
      print @cmd 
      exec(@cmd) 
     end 
     close cmds 
     deallocate cmds"; 

    private const string LookupEdmMetaDataTable = 
     @"Select COUNT(*) 
     FROM INFORMATION_SCHEMA.TABLES T 
     Where T.TABLE_NAME = 'EdmMetaData'"; 
} 

&

public class Population : DontDropDbJustCreateTablesIfModelChanged</* DbContext */> 
{ 
    protected override void Seed(Syndication Context) 
    { 
     /* Seeding :) */ 
    } 
} 

&

Database.SetInitializer</* DbContext */>(new Population());