2011-03-16 18 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类的相似查询

相关问题