Entity framework 4.1 如何在DontDropDbJustCreateTablesIfModelChanged之后为数据库种子

Entity framework 4.1 如何在DontDropDbJustCreateTablesIfModelChanged之后为数据库种子,entity-framework-4.1,ef-code-first,Entity Framework 4.1,Ef Code First,最近我的数据库权限被减少了,所以我不能删除和重新创建数据库。这导致我使用了来自nuget的DontDropDbJustCreateTablesIfModelChanged数据库初始化 然而,我现在被困在如何为数据设定种子上,因为种子函数不在初始化中,所以我无法覆盖它。这就是我希望能够做到的 public class MyDBInitialiser : DontDropDbJustCreateTablesIfModelChanged<MyContext> { protected

最近我的数据库权限被减少了,所以我不能删除和重新创建数据库。这导致我使用了来自nuget的DontDropDbJustCreateTablesIfModelChanged数据库初始化

然而,我现在被困在如何为数据设定种子上,因为种子函数不在初始化中,所以我无法覆盖它。这就是我希望能够做到的

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"});
    }
}
公共类MyDBInitialiser:DontDropDbJustCreateTablesIfModelChanged
{
受保护的覆盖无效种子(MyContext上下文)
{
种子(上下文);
Add(newitem(){ItemId=1,Name=“Item 1”});
Add(newitem(){ItemId=2,Name=“Item 2”});
Add(newitem(){ItemId=3,Name=“Item 3”});
}
}

在这种情况下,是否有另一种方法可以对数据进行种子设定。

I我的项目我将数据库初始化与数据库种子设定分开。如果使用控制反转,您应该能够在合成根目录中执行类似的操作(如果您正在使用web应用程序中的DbContext,则应用程序启动):

一种可能的实施方式:

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();
    }
}
简单地说

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'";
}
公共类DontDropDbJustCreateTablesIfModelChanged
:IDatabaseInitializer,其中T:DbContext
{
私有元数据(edmu-edmmadata);;
公共无效初始化数据库(T上下文)
{
ObjectContext对象上下文=
((IObjectContextAdapter)上下文);
字符串modelHash=GetModelHash(objectContext);
if(CompatibleWithModel(modelHash、context、objectContext))
返回;
删除现有表(objectContext);
CreateTables(objectContext);
SaveModelHashToDatabase(上下文、modelHash、objectContext);
种子(上下文);
}
受保护的虚拟空种子(T上下文){}
私有void SaveModelHashToDatabase(T上下文、字符串modelHash、,
对象上下文(ObjectContext)
{
如果(\u edmMetaData!=null)objectContext.Detach(\u edmMetaData);
_edmMetaData=新的edmMetaData();
context.Set().Add(_);
_edmMetaData.ModelHash=ModelHash;
SaveChanges();
}
私有void CreateTables(ObjectContext ObjectContext)
{
字符串数据库创建脚本=
objectContext.CreateDatabaseScript();
ExecuteStoreCommand(dataBaseCreateScript);
}
私有void DeleteExistingTables(ObjectContext ObjectContext)
{
ExecuteStoreCommand(Dropallconstraintsscript);
ExecuteStoreCommand(Deletealltablesscript);
}
私有字符串GetModelHash(ObjectContext上下文)
{
var csdlXmlString=GetCsdlXmlString(context.ToString();
返回计算ha256hash(csdlXmlString);
}
private bool CompatibleWithModel(字符串模型哈希、DbContext上下文、,
对象上下文(ObjectContext)
{
var IsedMetadataInstore=
objectContext.ExecuteStoreQuery(LookupedMetadataTable)
.FirstOrDefault();
if(ISEDMMataInstore==1)
{
_edmMetaData=context.Set().FirstOrDefault();
如果(_=null)
{
返回modelHash==\u edmtadata.modelHash;
}
}
返回false;
}
私有字符串GetCsdlXmlString(ObjectContext上下文)
{
if(上下文!=null)
{
var entityContainerList=context.MetadataWorkspace
.GetItems(DataSpace.SSpace);
if(entityContainerList!=null)
{
var entityContainer=entityContainerList.FirstOrDefault();
无功发生器=
新EntityModelSchemaGenerator(entityContainer);
var stringBuilder=新的stringBuilder();
var xmlWRiter=xmlWRiter.Create(stringBuilder);
generator.GenerateMetadata();
generator.WriteModelSchema(xmlWRiter);
xmlWRiter.Flush();
返回stringBuilder.ToString();
}
}
返回字符串。空;
}
私有静态字符串计算ha256hash(字符串输入)
{
字节[]缓冲区=新的SHA256Managed()
.ComputeHash(编码.ASCII.GetBytes(输入));
var builder=新的StringBuilder(buffer.Length*2);
foreach(缓冲区中的字节数)
{
builder.Append(num.ToString(“X2”,
文化信息(不变量文化);
}
返回builder.ToString();
}
私有常量字符串Dropallconstraintsscript=
@“选择
“ALTER TABLE”+so.TABLE_name+“DROP CONSTRAINT”
+那么,你的名字呢
从信息_SCHEMA.TABLE_CONSTRAINTS so”;
私有常量字符串Deletealltablesscript=
@“声明@cmd varchar(4000)
声明的cmds游标
挑选
'drop table['+table_Name+']
从…起
信息\u SCHEMA.TABLES
开放式cmds
而1=1
开始
将cmds提取到@cmd中
如果@fetch_status!=0,则中断
打印@cmd
exec(@cmd)
结束
关闭cmds
取消分配cmds”;
私有常量字符串LookupedMetadataTable=
@“选择计数(*)
来自信息\u SCHEMA.T表
其中T.TABLE_NAME='EdmMetaData';
}
&

公共类填充:DontDropDbJustCreateTablesIfModelChanged
{
受保护的覆盖无效种子(联合上下文)
{
/*播种:)*/
}
}
&

Database.SetInitializer(new Population());

谢谢,这让我走出了思维低谷,用不同的方式思考这个问题。没问题。顺便说一句,我的github帐户中有几个项目可以帮助使用ServiceProviderLocator和ServiceProviderExtension方法
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();
    }
}
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());