Changing schema name on runtime - Entity Framework

前端 未结 6 650
梦谈多话
梦谈多话 2020-12-01 04:12

I need to change the storage schema of the entities on runtime. I\'ve followed a wonderful post, available here: http://blogs.microsoft.co.il/blogs/idof/archive/2008/08/22/c

6条回答
  •  我在风中等你
    2020-12-01 04:37

    Well, I was looking for this piece of code all around the Internet. In the end I had to do it myself. It's based on Brandon Haynes adapter, but this function is all you need to change the schema on runtime - and you don't need to replace the autogenerated context constructors.

    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);
    }
    

    The resulting EntityConnection should be passed as a parameter when instantiating the context. You can modify it, so all ssdl models are modified by this function, not only the specified one.

提交回复
热议问题