在运行时更改模式名称 - 实体框架

nir*_*rpi 22 schema entity-framework runtime

我需要在运行时更改实体的存储架构.我已经关注了一篇很棒的帖子,可以在这里找到:http: //blogs.microsoft.co.il/blogs/idof/archive/2008/08/22/change-entity-framework-storage-db-schema-in-runtime的.aspx?CommentPosted =真#commentmessage

这非常有效,但仅适用于查询,不适用于修改.

知道为什么吗?

Jan*_*sek 25

好吧,我在互联网上寻找这段代码.最后我必须自己做.它基于Brandon Haynes适配器,但是此功能是您在运行时更改模式所需的全部功能 - 您无需替换自动生成的上下文构造函数.

public static EntityConnection Create(
    string schema, string connString, string model)
{
    XmlReader[] conceptualReader = new XmlReader[]
    {
        XmlReader.Create(
            Assembly
                .GetExecutingAssembly()
                .GetManifestResourceStream(model + ".csdl")
        )
    };
    XmlReader[] mappingReader = new XmlReader[]
    {
        XmlReader.Create(
            Assembly
                .GetExecutingAssembly()
                .GetManifestResourceStream(model + ".msl")
        )
    };

    var storageReader = XmlReader.Create(
        Assembly
            .GetExecutingAssembly()
            .GetManifestResourceStream(model + ".ssdl")
    );
    XNamespace storageNS = "http://schemas.microsoft.com/ado/2009/02/edm/ssdl";

    var storageXml = XElement.Load(storageReader);

    foreach (var entitySet in storageXml.Descendants(storageNS + "EntitySet"))
    {   
        var schemaAttribute = entitySet.Attributes("Schema").FirstOrDefault();
        if (schemaAttribute != null)
        {
            schemaAttribute.SetValue(schema);
        }
    }
    storageXml.CreateReader();

    StoreItemCollection storageCollection =
        new StoreItemCollection(
            new XmlReader[] { storageXml.CreateReader() }
        );
    EdmItemCollection conceptualCollection = new EdmItemCollection(conceptualReader);
    StorageMappingItemCollection mappingCollection =
        new StorageMappingItemCollection(
            conceptualCollection, storageCollection, mappingReader
        );

    var workspace = new MetadataWorkspace();
    workspace.RegisterItemCollection(conceptualCollection);
    workspace.RegisterItemCollection(storageCollection);
    workspace.RegisterItemCollection(mappingCollection);

    var connectionData = new EntityConnectionStringBuilder(connString);
    var connection = DbProviderFactories
        .GetFactory(connectionData.Provider)
        .CreateConnection();
    connection.ConnectionString = connectionData.ProviderConnectionString;

    return new EntityConnection(workspace, connection);
}
Run Code Online (Sandbox Code Playgroud)

在实例化上下文时,应将生成的EntityConnection作为参数传递.您可以修改它,因此所有ssdl模型都由此函数修改,而不仅仅是指定的模型.


nir*_*rpi 11

我设法通过使用位于CodePlex(由Brandon Haynes提供)的名为"实体框架运行时模型适配器"的精彩库来解决此问题,可在此处获取:http: //efmodeladapter.codeplex.com/

我已经调整了一下,以满足我们的需求,而根本不需要更换设计器代码.

所以,我很好.

无论如何,谢谢,特别是布兰登,这是一项了不起的工作!


msa*_*sa7 5

我需要从postgres数据库导入数据.它默认使用模式"public".所以我使用Entity Framework CTP 4"Code first".它默认使用模式"dbo".要在运行时更改它,我使用:

public class PublicSchemaContext : DbContext
{
    protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder builder)
    {
        builder.Entity<series_categories>().MapSingleType().ToTable("[public].[series_categories]");
    }

    public DbSet<series_categories> series_categories { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

它适用于选择,插入,更新和删除数据.通过下一次测试:

[Test]
        public void AccessToPublicSchema()
        {
            // Select
            var db = new PublicSchemaContext();
            var list = db.series_categories.ToList();
            Assert.Greater(list.Count, 0);
            Assert.IsNotNull(list.First().series_category);

            // Delete
            foreach (var item in db.series_categories.Where(c => c.series_category == "Test"))
                db.series_categories.Remove(item);
            db.SaveChanges();

            // Insert
            db.series_categories.Add(new series_categories { series_category = "Test", series_metacategory_id = 1 });
            db.SaveChanges();

            // Update
            var test = db.series_categories.Single(c => c.series_category == "Test");
            test.series_category = "Test2";
            db.SaveChanges();

            // Delete
            foreach (var item in db.series_categories.Where(c => c.series_category == "Test2"))
                db.series_categories.Remove(item);
            db.SaveChanges();
        }
Run Code Online (Sandbox Code Playgroud)