2011-03-16 56 views
0

場景:我要動態地選擇基於該應用程序在運行環境中的連接字符串如何覆蓋連接斯汀在自動生成的實體模型代碼

環境:我有兩個環境開發和爲WCF服務生產。我將連接字符串存儲在web.config中。當該應用程序啓動時,請使用正確的連接字符串設置變量。

問題: 生成數據模型時,它會創建2個文件dmMyDataModel.edmx和dmMyDataModel.Designer.cs,在設計器文件中有構造函數定義與EntityDatabas的連接。

在下面的代碼中,您可以看到我在服務中創建了一個構造函數,當調用該服務時,它將設置上下文以使用正確的連接字符串。但只有使用myContext的項目才能正常工作(存儲過程)dbMyWebSiteEntities的查詢在生產環境中失敗,因爲仍依賴於設計器中設置的連接字符串。

我厭倦了設計師的邏輯,但是當它重新生成時就會被抹去。

dmMyDataModel.Designer.cs

using System; 
using System.Data.Objects; 
using System.Data.Objects.DataClasses; 
using System.Data.EntityClient; 
using System.ComponentModel; 
using System.Xml.Serialization; 
using System.Runtime.Serialization; 

[assembly: EdmSchemaAttribute()] 

namespace MyWebSite.Services 
{ 
    #region Contexts 

    /// <summary> 
    /// No Metadata Documentation available. 
    /// </summary> 
    public partial class dbMyWebSiteEntities : ObjectContext 
    { 
     #region Constructors 

     /// <summary> 
     /// Initializes a new dbMyWebSiteEntities object using the connection string found in the 'dbMyWebSiteEntities' section of the application configuration file. 
     /// </summary> 
     public dbMyWebSiteEntities() : base("name=dbMyWebSiteEntities", "dbMyWebSiteEntities") 
     { 
      this.ContextOptions.LazyLoadingEnabled = true; 
      OnContextCreated(); 
     } 

     /// <summary> 
     /// Initialize a new dbMyWebSiteEntities object. 
     /// </summary> 
     public dbMyWebSiteEntities(string connectionString) : base(connectionString, "dbMyWebSiteEntities") 
     { 
      this.ContextOptions.LazyLoadingEnabled = true; 
      OnContextCreated(); 
     } 
     /// <summary> 
     /// Initialize a new dbMyWebSiteEntities object. 
     /// </summary> 
     public dbMyWebSiteEntities(EntityConnection connection) : base(connection, "dbMyWebSiteEntities") 
     { 
      this.ContextOptions.LazyLoadingEnabled = true; 
      OnContextCreated(); 
     } 

     #endregion 
     ... 
    } 

MyWebSiteData.svc.cs

using System; 
using System.Collections.Generic; 
using System.Data.Services; 
using System.Data.Services.Common; 
using System.Linq; 
using System.ServiceModel.Web; 
using System.Web; 
using System.ServiceModel.Activation; 
using System.ServiceModel; 
using System.Data.EntityClient; 
using System.Configuration; 
using System.Data.Objects; 

namespace MyWebSite.Services 
{ 
    public class MyWebSiteData : DataService<dbMyWebSiteEntities> 
    { 
     private dbMyWebSiteEntities myContext; 

     public static void InitializeService(DataServiceConfiguration config) 
     { 
      config.UseVerboseErrors = true; 
      config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2; 
      config.SetEntitySetAccessRule("*", EntitySetRights.AllRead); 
      config.SetEntitySetPageSize("*", 25); 

      config.SetServiceOperationAccessRule("mar_getAllByKey", ServiceOperationRights.AllRead); 
     } 

     //Constructor to override the connection string used in the dmMyDataModel.Designer.cs 
     public MyWebSiteData() 
     { 
      //sets the connetion string and appends the environment so it will pull the correct one from the web.config 
      EntityConnection conn = new EntityConnection("name=dbMyWebSiteEntities" + HttpContext.Current.Application["Environment"]); 
      myContext = new dbMyWebSiteEntities(conn); 
     } 

     //This returns the data from the stored procedures 
     [WebGet] 
     public ObjectResult<myTable> mar_getAllByKey(string key) 
     { 
      return myContext.mar_getAllByKey(key); 
     } 
    } 
} 

感謝您抽出寶貴時間來看看這個。我試圖具體而詳細,但如果我留下了一些讓我知道。

謝謝, 傑拉德

回答

4

生成的類是partial。如果你想添加新的構造函數,定義另一個分類類(相同的類名和命名空間)是一個不同的文件,並在那裏添加你的構造函數。您的文件不會被重新生成。這就是partial關鍵字的用途。

您的新構造函數必須是唯一的 - 不同的參數。

你也可以在你的部分類中定義一個靜態工廠方法,它將封裝實例化的邏輯。

我在.config文件中爲每個環境(Dev/Test/Beta/Prod)使用Xml Transformations設置不同的連接字符串。

+0

是大腦的例子波紋管你談論「靜態工廠方法」 ?對不起,我仍然把頭繞在OOP上。 – Gerald 2011-03-16 22:47:27

+0

@傑拉德 - 是的。 – 2011-03-17 08:47:42

0

最好的辦法是創建一個包裝:

public static class DBContextCreator 
{ 
    public static MyDBContext Create() 
    { 
     return new MyDBContext(/* pass in connection of choice here */); 
    } 
} 

在這個包裝就可以通過各種方式處理不同的邏輯。

HTH。

+0

嗨,布萊恩。這創建了一個新的上下文。當服務啓動時,它會從生成的設計器中創建一個上下文,這是我希望能夠更改連接字符串的那個。當我喜歡你上面提出的建議時,它會創建一個新實例,並且只會在使用新的上下文時使用正確的連接字符串。 – Gerald 2011-03-16 22:40:43

+0

您不能更改連接字符串;在創建對象上下文時必須建立連接,並且在此之後不能再進行更改。改變它意味着重新實現上下文。如果您有任何LINQ對象,則必須將它們從現有上下文中分離出來,並將它們重新附加到新的上下文中。 – 2011-03-17 16:20:01

0

您可以找到超過here

它給例如命名空間System.Data.Common.DbConnectionStringBuilder使用EntityConnectionStringBuilder類的相似查詢

相關問題