これは、AppHarborでEFコードを最初に実行する最も簡単な方法です。
このEdmMetadata.TryGetModelHash(context)
関数を使用して、モデルがデータベースと一致しない場合を確認し、変更スクリプトの実行後に使用する必要がある新しいコードでエラーを表示します。
PopulateOnly:データベースが空の場合にのみオブジェクトを作成します
既存のデータベースにデータを入力するために、現在appharborで使用しているInitializerの独自のバージョンを投稿すると思いました。また、データベースが存在しない場合は作成を試み、変更が検出された場合はスローします(自動更新はまだありません)。誰かがそれが役に立つと思うことを願っています。
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Objects;
using System.Transactions;
namespace Deskspace.EntityFramework
{
/// <summary> A Database Initializer for appharbor </summary>
/// <typeparam name="T">Code first context</typeparam>
public class PopulateOnly<T> : IDatabaseInitializer<T> where T : DbContext
{
private EdmMetadata metadata;
private enum Status
{
Compatable,
Invalid,
Missing
}
/// <summary> Initializer that supports creating or populating a missing or empty database </summary>
/// <param name="context"> Context to create for </param>
public void InitializeDatabase(T context)
{
// Get metadata hash
string hash = EdmMetadata.TryGetModelHash(context);
bool exists;
using (new TransactionScope( TransactionScopeOption.Suppress )) {
exists = context.Database.Exists();
}
if (exists) {
ObjectContext objectContext = ((IObjectContextAdapter)context).ObjectContext;
var dbHash = GetHashFromDatabase( objectContext );
Status compatability =
string.IsNullOrEmpty( dbHash )?
Status.Missing :
(dbHash != hash)?
Status.Invalid :
Status.Compatable;
if (compatability == Status.Missing) {
// Drop all database objects
ClearDatabase( objectContext );
// Recreate database objects
CreateTables( objectContext );
// Save the new hash
SaveHash( objectContext, hash );
} else if (compatability == Status.Invalid) {
throw new Exception(
"EdmMetadata does not match, manually update the database, expected: " +
Environment.NewLine +
"<[(" + hash + ")}>"
);
}
} else {
context.Database.Create();
context.SaveChanges();
}
}
private void ClearDatabase(ObjectContext objectContext)
{
objectContext.ExecuteStoreCommand( DropAllObjects );
}
private void CreateTables(ObjectContext objectContext)
{
string dataBaseCreateScript = objectContext.CreateDatabaseScript();
objectContext.ExecuteStoreCommand( dataBaseCreateScript );
}
private void SaveHash(ObjectContext objectContext, string hash)
{
objectContext.ExecuteStoreCommand( string.Format(UpdateEdmMetaDataTable, hash.Replace( "'", "''" )) );
}
private string GetHashFromDatabase(ObjectContext objectContext)
{
foreach (var item in objectContext.ExecuteStoreQuery<string>( GetEdmMetaDataTable )) {
return item;
}
return string.Empty;
}
private const string UpdateEdmMetaDataTable = @"
Delete From EdmMetadata;
Insert Into EdmMetadata (ModelHash) Values ('{0}');";
private const string GetEdmMetaDataTable = @"
If Exists (Select * From INFORMATION_SCHEMA.TABLES tables where tables.TABLE_NAME = 'EdmMetaData')
Select Top 1 ModelHash From EdmMetadata;
Else
Select '';";
private const string DropAllObjects = @"
declare @n char(1)
set @n = char(10)
declare @stmt nvarchar(max)
-- procedures
select @stmt = isnull( @stmt + @n, '' ) +
'drop procedure [' + name + ']'
from sys.procedures
-- check constraints
select @stmt = isnull( @stmt + @n, '' ) +
'alter table [' + object_name( parent_object_id ) + '] drop constraint [' + name + ']'
from sys.check_constraints
-- functions
select @stmt = isnull( @stmt + @n, '' ) +
'drop function [' + name + ']'
from sys.objects
where type in ( 'FN', 'IF', 'TF' )
-- views
select @stmt = isnull( @stmt + @n, '' ) +
'drop view [' + name + ']'
from sys.views
-- foreign keys
select @stmt = isnull( @stmt + @n, '' ) +
'alter table [' + object_name( parent_object_id ) + '] drop constraint [' + name + ']'
from sys.foreign_keys
-- tables
select @stmt = isnull( @stmt + @n, '' ) +
'drop table [' + name + ']'
from sys.tables
-- user defined types
select @stmt = isnull( @stmt + @n, '' ) +
'drop type [' + name + ']'
from sys.types
where is_user_defined = 1
exec sp_executesql @stmt";
}
}