c# Entity Framework EF 4.1 Change Schema and Database name at runtime

后端 未结 1 1560
长发绾君心
长发绾君心 2021-01-25 17:04

I´ve searched for some topics, but did not find a concrete solution to my problem.

My app is a c# commercial app. I´m using EF 4.1 database first. I generate the model f

相关标签:
1条回答
  • 2021-01-25 17:43

    Actually, I needed solution for this too. I quickly whipped up solution, which works nicely. I didn't find much information about this in Internet, so I am not sure about the "EF 4.1 comes with better support tools to do it".

    The concrete example "Changing schema name on runtime - Entity framework" didn't entirely work for me, however with some minor modifications I got it working.

    Here is a DatabaseUtils class that can do it:

    internal static class DatabaseUtils
    {
        /// <summary>
        /// Builds the connection string for Entity framework.
        /// </summary>
        /// <returns></returns>
        public static EntityConnection BuildConnection(BuildConnectionParams buildConnectionParams)
        {
            var sqlBuilder = new SqlConnectionStringBuilder
                {
                    DataSource = buildConnectionParams.ServerName,
                    InitialCatalog = buildConnectionParams.DatabaseName,
                    IntegratedSecurity = true
                };
    
            var providerString = sqlBuilder.ToString();
            var entityBuilder = new EntityConnectionStringBuilder
            {
                Provider = buildConnectionParams.ProviderName,
                ProviderConnectionString = providerString,
                Metadata = string.Format(@"res://*/{0}.csdl|
                            res://*/{0}.ssdl|
                            res://*/{0}.msl", buildConnectionParams.ModelName)
            };
    
            return CreateConnection(buildConnectionParams.SchemaName, entityBuilder, buildConnectionParams.ModelName);
        }
    
    
        /// <summary>
        /// Creates the EntityConnection, based on new schema & existing connectionString
        /// </summary>
        /// <param name="schemaName">Name of the schema.</param>
        /// <param name="connectionBuilder"></param>
        /// <param name="modelName">Name of the model.</param>
        /// <returns></returns>
        private static EntityConnection CreateConnection(string schemaName, EntityConnectionStringBuilder connectionBuilder, string modelName)
        {
            Func<string, Stream> generateStream =
                extension => Assembly.GetExecutingAssembly().GetManifestResourceStream(string.Concat(modelName, extension));
    
            Action<IEnumerable<Stream>> disposeCollection = streams =>
            {
                if (streams == null)
                    return;
    
                foreach (var stream in streams.Where(stream => stream != null))
                    stream.Dispose();
            };
    
            var conceptualReader = generateStream(".csdl");
            var mappingReader = generateStream(".msl");
            var storageReader = generateStream(".ssdl");
    
            if (conceptualReader == null || mappingReader == null || storageReader == null)
            {
                disposeCollection(new[] { conceptualReader, mappingReader, storageReader });
                return null;
            }
    
            var storageXml = XElement.Load(storageReader);
    
            foreach (var entitySet in storageXml.Descendants())
            {
                var schemaAttribute = entitySet.Attributes("Schema").FirstOrDefault();
                if (schemaAttribute != null)
                    schemaAttribute.SetValue(schemaName);
            }
    
            storageXml.CreateReader();
    
            var workspace = new MetadataWorkspace();
    
            var storageCollection = new StoreItemCollection(new[] { storageXml.CreateReader() });
            var conceptualCollection = new EdmItemCollection(new[] { XmlReader.Create(conceptualReader) });
            var mappingCollection = new StorageMappingItemCollection(conceptualCollection, 
                                                                    storageCollection,
                                                                    new[] { XmlReader.Create(mappingReader) });
    
            workspace.RegisterItemCollection(conceptualCollection);
            workspace.RegisterItemCollection(storageCollection);
            workspace.RegisterItemCollection(mappingCollection);
    
            var connection = DbProviderFactories.GetFactory(connectionBuilder.Provider).CreateConnection();
            if (connection == null)
            {
                disposeCollection(new[] { conceptualReader, mappingReader, storageReader });
                return null;
            }
    
            connection.ConnectionString = connectionBuilder.ProviderConnectionString;
            return new EntityConnection(workspace, connection);
        }
    }
    

    Usage:

    /// <summary>
    /// Initializes a new instance of the <see cref="DynamicAQDContext"/> class.
    /// </summary>
    public DynamicAQDContext()
    {
        var entityConnection = DatabaseUtils.BuildConnection(new BuildConnectionParams
        {
            ProviderName = "System.Data.SqlClient",
            ServerName = "localhost\\",
            DatabaseName = "",
            ModelName = "YOURMODEL",
            SchemaName = "SCHEMA"
        });
    
        if(entityConnection == null)
            throw new Exception("Can't create EntityConnection");
    
        _entities = new LINKEntities(entityConnection);
    }
    

    more info can be found here: http://bestplayah.com/entity-framework-dynamic-schema-changes-using-database-first-approach/

    0 讨论(0)
提交回复
热议问题