新文章

2013年8月27日 星期二

[C#]Entity Frame Work Connection String Modify and Read in App.config Part.1

最近因專案上的需要,研究了一下app.configEF上的connection相關使用方法,想當然爾碰到了不少問題,在檢視了一些解決方案後有些許心得記錄如下
Preface
I studied some documents about app.config connection in EF for the sake of my project .Naturally, I encountered some problems. After I got the solutions and some explorations, here is the records of my own.


主題依序為
1.          修改app.config連線
A.          修改來自給予的路徑
B.          修改來自本身程式(即時)
2.          取得app.config連線內容
The subjects are ordered below:
1.          Modified the connection in app.config
A.          Modified the connection from giving path
B.          Modified the connection from current application (at run time)
2.          Get the connection from app.config


主題1 : 修改app.config連線
A. 修改來自給予的路徑
Subject 1: Modified the connection in app.config
A. Modified the connection from giving path


這邊給予簡單的code snippets 介紹如何變更app.config的連線,並且使用了加密方法
首先是app.config範例
Here is the simple code snippets introduce about how to modify the app.config and use the encryption in connection strings.
First,here is the example of app.config below:
<?xml version="1.0" encoding="utf-8"?>

<configuration>

  <configSections></configSections>

<connectionStrings>

<add name="Test_managementEntities" connectionString="metadata=res://*/lib.UploadServer.ServerDBModel.csdl|res://*/lib.UploadServer.ServerDBModel.ssdl|res://*/lib.UploadServer.ServerDBModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=127.0.0.0;Initial Catalog=TestDB;User ID=test;Password=test;MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" />

</connectionStrings>

</configuration>


修改來自給予的路徑
Modified the connection from giving path
public bool UpdateEFConnByPath(string m_DataSource, string m_InitialCatalog, string m_UserID, string m_Password, bool m_PersistSecurityInfo, bool m_MultipleActiveResultSets,string m_Entities,string m_ConfigPath)

        {

            try

            {

                //Find the app.config path

                var exeConfigurationFileMap = new ExeConfigurationFileMap();

                exeConfigurationFileMap.ExeConfigFilename = m_ConfigPath;



                var config = ConfigurationManager.OpenMappedExeConfiguration(exeConfigurationFileMap, ConfigurationUserLevel.None);



                // Because it's an EF connection string it's not a normal connection string

                // so we pull it into the EntityConnectionStringBuilder instead

                EntityConnectionStringBuilder efb =

                    new EntityConnectionStringBuilder(

                        config.ConnectionStrings.ConnectionStrings[m_Entities]

                            .ConnectionString);

                // Then we extract the actual underlying provider connection string

                SqlConnectionStringBuilder sqb =

                    new SqlConnectionStringBuilder(efb.ProviderConnectionString);

                // Now we can set the datasource

                sqb.DataSource = m_DataSource;

                sqb.InitialCatalog = m_InitialCatalog;

                sqb.UserID = m_UserID;

                sqb.Password = m_Password;

                sqb.PersistSecurityInfo = m_PersistSecurityInfo;

                sqb.MultipleActiveResultSets = m_MultipleActiveResultSets;





                // Pop it back into the EntityConnectionStringBuilder

                efb.ProviderConnectionString = sqb.ConnectionString;



                // And update...

                config.ConnectionStrings.ConnectionStrings[m_Entities]

                    .ConnectionString = efb.ConnectionString;



                config.Save(ConfigurationSaveMode.Modified, true);

                ConfigurationManager.RefreshSection("connectionStrings");

                return true;

            }

            catch

            {

                return false;

            }

        }

主題1 : 修改app.config連線
B. 修改來自本身程式(即時)
Subject 1: Modified the connection in app.config
B.Modified the connection from current application (at run time)

這和上述程式碼非常相似,只是我們要做的是在runtime重新讀取config狀態
This method is as same as above method.What we nedd to do is reload the state of config at runtime.

public bool UpdatecCurrentEFConn(string m_DataSource, string m_InitialCatalog, string m_UserID, string m_Password, bool m_PersistSecurityInfo, bool m_MultipleActiveResultSets, string m_Entities)

        {

            try

            {

                Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);



                EntityConnectionStringBuilder efb =

                    new EntityConnectionStringBuilder(

                        config.ConnectionStrings.ConnectionStrings[m_Entities]

                            .ConnectionString);



                SqlConnectionStringBuilder sqb =

                    new SqlConnectionStringBuilder(efb.ProviderConnectionString);

                // set the datasource

                sqb.DataSource = m_DataSource;

                sqb.InitialCatalog = m_InitialCatalog;

                sqb.UserID = m_UserID;

                sqb.Password = m_Password;

                sqb.PersistSecurityInfo = m_PersistSecurityInfo;

                sqb.MultipleActiveResultSets = m_MultipleActiveResultSets;





                // Pop it back into the EntityConnectionStringBuilder

                efb.ProviderConnectionString = sqb.ConnectionString;



                // update

                config.ConnectionStrings.ConnectionStrings[m_Entities]

                    .ConnectionString = efb.ConnectionString;



                //save the file

                config.Save(ConfigurationSaveMode.Modified, true);



                ConfigurationManager.RefreshSection(config.AppSettings.SectionInformation.Name);

                //reload the config

                ResetConfigMechanism();

                return true;

            }

            catch (Exception)

            {

                return false;

            }

        }

       

        public static void ResetConfigMechanism()

        {

            typeof(ConfigurationManager)

                .GetField("s_initState", BindingFlags.NonPublic |

                                         BindingFlags.Static)

                .SetValue(null, 0);



            typeof(ConfigurationManager)

                .GetField("s_configSystem", BindingFlags.NonPublic |

                                            BindingFlags.Static)

                .SetValue(null, null);



            typeof(ConfigurationManager)

                .Assembly.GetTypes()

                .Where(x => x.FullName ==

                            "System.Configuration.ClientConfigPaths")

                .First()

                .GetField("s_current", BindingFlags.NonPublic |

                                       BindingFlags.Static)

                .SetValue(null, null);

        }
id



在SqlConnectionStringBuilder的屬性可以根據自身需求增加進方法中,詳情可以參考:
The attributes of SqlConnectionStringBuilder in method can add optional arguments of your own and the refrences here:

SqlConnectionStringBuilder Class
EntityConnectionStringBuilder Class

加密連線字串
Encrypt the connection strings

public static void EncryptConnectionString(bool encrypt, Configuration configFile)

        {
            try

            {

                // Open the configuration file and retrieve the connectionStrings section.

                ConnectionStringsSection configSection = configFile.GetSection("connectionStrings") as ConnectionStringsSection;



                if ((!(configSection.ElementInformation.IsLocked)) && (!(configSection.SectionInformation.IsLocked)))

                {

                    if (encrypt && !configSection.SectionInformation.IsProtected)//encrypt is false to unencrypt

                    {

                        configSection.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");

                    }



                    if (!encrypt && configSection.SectionInformation.IsProtected)//encrypt is true so encrypt

                    {

                        configSection.SectionInformation.UnprotectSection();

                    }



                    //re-save the configuration file section

                    configSection.SectionInformation.ForceSave = true;



                    // Save the current configuration.

                    configFile.Save();

                }

            }

            catch (System.Exception ex)

            {

                throw (ex);

            }

            finally

            {

            }

        }




沒有留言:

張貼留言