如何在运行时更改EF模式和连接字符串(生产到开发环境)

时间:2014-03-06 23:10:29

标签: c# asp.net oracle entity-framework oracle11g

我被困在一个小型网站的ASP.NET应用程序中。我使用EF5和Oracle的.Net提供程序使用数据库第一种方法。

一切正常,除了我需要在运行时从生产环境切换到开发环境而不触及任何配置文件(如Web.config文件)。

在Oracle中,由于我想连接到不同的数据库,我需要调用不同的连接字符串。我目前的连接字符串是(EZ表示法):

MyProductionUserName/MyProductionPassword@192.168.0.200/XE - 适用于生产环境 MyDevUserName/MyDevPassword@192.168.0.200/XE - 对于开发环境。

首先使用数据库时,EF工具会构建以下模型:

namespace DataAccessOracleModel.Model
{
    using System;
    using System.Data.Entity;
    using System.Data.Entity.Infrastructure;

    public partial class Entities : DbContext
    {
        public Entities()
            : base("name=Entities")
        {
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            throw new UnintentionalCodeFirstException();
        }

        public DbSet<TABLE1> TABLE1 { get; set; }
        public DbSet<TABLE2> TABLE2 { get; set; }
        public DbSet<TABLE3> TABLE3 { get; set; }
        .
        .
        .
        public DbSet<TABLEn> TABLEn { get; set; }
    }
}

TABLE1, TABLE2, TABLE3, TABLEn是我的所有数据库表。 我无法触及上面的代码,因为它是自动生成的。

所以,这就是我已经做过的事情:

查看this link并回答我自己的帖子here,我推出了这些课程:

public static class ConnectionHelper
    {
        /// <summary>
        /// Builds the connection string for Entity framework on Oracle.
        /// </summary>
        /// <returns></returns>
        public static EntityConnection BuildOracleConnection(OracleConnectionParams connectionParams)
        {

            string oraConnectionString = "DATA SOURCE=192.168.0.200:1521/XE;PERSIST SECURITY INFO=True;USER ID=MyDevUsername;PASSWORD=MyDevPassword"; /// Test connection string for the development environment

            var entityBuilder = new EntityConnectionStringBuilder
            {
                Provider = "Oracle.ManagedDataAccess.Client", // or System.Data.EntityClient?
                ProviderConnectionString = oraConnectionString,
                Metadata = string.Format(@"res://*/{0}.csdl|
                        res://*/{0}.ssdl|
                        res://*/{0}.msl", connectionParams.ModelName)
            };

            return CreateConnection(connectionParams.UserId, entityBuilder, connectionParams.ModelName);
        }


        /// <summary>
        /// Creates the EntityConnection, based on new schema & existing connectionString. Use reflection to get the model and them 
        /// change the internal files.
        /// </summary>
        /// <param name="schemaName">Name of the schema.</param>
        /// <param name="connectionBuilder">The string builder for the connection string</param>
        /// <param name="modelName">Name of the model.</param>
        /// <returns></returns>
        public 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");

            ///
            /// Get the EF file pointers
            /// 
            if (conceptualReader == null || mappingReader == null || storageReader == null)
            {
                disposeCollection(new[] { conceptualReader, mappingReader, storageReader });
                return null;
            }

            ///
            /// Change the storage reader
            /// 
            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);
        }
    }
}

    /// <summary>
    /// Define parameters used for Oracle database connection. Used to build the connection string at runtime.
    /// </summary>
    public class OracleConnectionParams
    {
        /// <summary>
        /// Name of provider
        /// </summary>
        public string Host { get; set; }

        /// <summary>
        /// Database server name 
        /// </summary>
        public string Port { get; set; }

        /// <summary>
        /// Database name
        /// </summary>
        public string Service { get; set; }

        /// <summary>
        /// Model name
        /// </summary>
        public string UserId { get; set; }

        /// <summary>
        /// Model name
        /// </summary>
        public string Password { get; set; }

        /// <summary>
        /// Model name
        /// </summary>
        public string ModelName { get; set; }
    }

但是当我想出2个不同的EntityConnections(EntitiesCreateConnection返回的那个)时,我感到困惑。问题:

我无法创建另一个实体,因为它是由EF工具创建的。我不想触摸EF原始代码,因为我们的开发方法是更改​​数据库,然后生成一个新的EF类(这一天要做几次)。

我正在使用EF5,我没有根据需要更改连接字符串的构造函数。

我需要让工作成为一个简单的控制台应用程序(非功能性):

namespace TestApp
{
    class Program
    {
        static void Main(string[] args)
        {
            SomeFunctionToSetDbContext("192.168.0.200", "1521", "XE", "MyDevUserId", "MyDevPassword");

            var testtableitens = TestTable1.List();

            foreach (var item in testtableitens)
                Console.WriteLine(item);
        }
    }
}

但正如我所说,我不知道去哪里“加入”这两个想法......非常感谢......

0 个答案:

没有答案