entity framework的连接字符串

我想在Silverlight中的多个实体之间共享相同的数据库信息..但我希望连接字符串被命名为xyz并让每个人都从machine.config访问该连接字符串…

实体的元数据部分将是不同的,因为我没有将实体命名为相同的..

我可以在该元数据部分放置多个实体吗?

这是一个例子..我想使用这个连接字符串,但请注意我在元数据部分放了多个实体。

基本上我想拿这个连接字符串

 

而这个连接字符串

   

制作此连接字符串

  

但它根本行不通。 这两个项目都无法连接到它。

 string encConnection = ConfigurationManager.ConnectionStrings[connectionName].ConnectionString; Type contextType = typeof(test_Entities); object objContext = Activator.CreateInstance(contextType, encConnection); return objContext as test_Entities; 

不幸的是,将多个实体上下文组合成单个命名连接是不可能的。 如果要使用.config文件中的命名连接字符串来定义entity framework连接,则每个连接都必须具有不同的名称。 按照惯例,该名称通常是上下文的名称:

   

但是,如果最终出现名称空间冲突,则可以使用所需的任何名称,并在生成时将其正确地传递给上下文:

 var context = new Entity("EntityV2"); 

显然,如果您使用工厂或dependency injection来生成上下文,则此策略最有效。

另一种选择是以编程方式生成每个上下文的整个连接字符串,然后将整个字符串传递给构造函数(而不仅仅是名称)。

 // Get "Data Source=SomeServer..." var innerConnectionString = GetInnerConnectionStringFromMachinConfig(); // Build the Entity Framework connection string. var connectionString = CreateEntityConnectionString("Entity", innerConnectionString); var context = new EntityContext(connectionString); 

这样的事情怎么样:

 Type contextType = typeof(test_Entities); string innerConnectionString = ConfigurationManager.ConnectionStrings["Inner"].ConnectionString; string entConnection = string.Format( "metadata=res://*/{0}.csdl|res://*/{0}.ssdl|res://*/{0}.msl;provider=System.Data.SqlClient;provider connection string=\"{1}\"", contextType.Name, innerConnectionString); object objContext = Activator.CreateInstance(contextType, entConnection); return objContext as test_Entities; 

…在你的machine.config中有以下内容:

  

这样,您可以为计算机上每个项目中的每个上下文使用单个连接字符串。

您可以使用带有作用域systemConfig表的配置数据库,而不是使用配置文件,并在那里添加所有设置。

 CREATE TABLE [dbo].[SystemConfig] ( [Id] [int] IDENTITY(1, 1) NOT NULL , [AppName] [varchar](128) NULL , [ScopeName] [varchar](128) NOT NULL , [Key] [varchar](256) NOT NULL , [Value] [varchar](MAX) NOT NULL , CONSTRAINT [PK_SystemConfig_ID] PRIMARY KEY NONCLUSTERED ( [Id] ASC ) WITH ( PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON ) ON [PRIMARY] ) ON [PRIMARY] GO SET ANSI_PADDING OFF GO ALTER TABLE [dbo].[SystemConfig] ADD CONSTRAINT [DF_SystemConfig_ScopeName] DEFAULT ('SystemConfig') FOR [ScopeName] GO 

使用这样的配置表,您可以创建如下行: 在此处输入图像描述

然后从您的应用程序dal(s)包装EF您可以轻松检索范围配置。
如果您没有使用dal并直接使用EF在线路中工作,则可以从SystemConfig表中创建一个实体,并根据您所在的应用程序使用该值。

首先尝试了解entity framework连接字符串的工作原理,然后您就会知道出了什么问题。

  1. 您有两个不同的模型,Entity和ModEntity
  2. 这意味着您有两个不同的上下文,每个上下文都有自己的存储模型,概念模型和两者之间的映射。
  3. 你只是组合了字符串,但实体的上下文如何知道它必须拾取e​​ntity.csdl而ModEntity将拾取modentity.csdl? 那么有人可以编写一些智能代码,但我不认为这是EF开发团队的主要角色。
  4. 还有machine.config是个坏主意。
  5. 如果将Web应用程序移动到不同的计算机或共享托管环境或用于维护目的,则可能会导致问题。
  6. 每个人都可以访问它,你让它变得不安全。 如果任何人都可以在服务器上部署Web应用程序或任何.NET应用程序,则他们可以完全访问您的连接字符串,包括敏感密码信息。

另一个替代方案是,您可以为您的上下文创建自己的构造函数并传递您自己的连接字符串,您可以编写一些if条件等来从web.config加载默认值

更好的办法是,保持连接字符串不变,为应用程序池提供一个可以访问数据库服务器的标识,并且不要在连接字符串中包含用户名和密码。

要使相同的edmx能够访问多个数据库和数据库提供程序,反之亦然,我使用以下技术:

1)定义ConnectionManager:

 public static class ConnectionManager { public static string GetConnectionString(string modelName) { var resourceAssembly = Assembly.GetCallingAssembly(); var resources = resourceAssembly.GetManifestResourceNames(); if (!resources.Contains(modelName + ".csdl") || !resources.Contains(modelName + ".ssdl") || !resources.Contains(modelName + ".msl")) { throw new ApplicationException( "Could not find connection resources required by assembly: " + System.Reflection.Assembly.GetCallingAssembly().FullName); } var provider = System.Configuration.ConfigurationManager.AppSettings.Get( "MyModelUnitOfWorkProvider"); var providerConnectionString = System.Configuration.ConfigurationManager.AppSettings.Get( "MyModelUnitOfWorkConnectionString"); string ssdlText; using (var ssdlInput = resourceAssembly.GetManifestResourceStream(modelName + ".ssdl")) { using (var textReader = new StreamReader(ssdlInput)) { ssdlText = textReader.ReadToEnd(); } } var token = "Provider=\""; var start = ssdlText.IndexOf(token); var end = ssdlText.IndexOf('"', start + token.Length); var oldProvider = ssdlText.Substring(start, end + 1 - start); ssdlText = ssdlText.Replace(oldProvider, "Provider=\"" + provider + "\""); var tempDir = Environment.GetEnvironmentVariable("TEMP") + '\\' + resourceAssembly.GetName().Name; Directory.CreateDirectory(tempDir); var ssdlOutputPath = tempDir + '\\' + Guid.NewGuid() + ".ssdl"; using (var outputFile = new FileStream(ssdlOutputPath, FileMode.Create)) { using (var outputStream = new StreamWriter(outputFile)) { outputStream.Write(ssdlText); } } var eBuilder = new EntityConnectionStringBuilder { Provider = provider, Metadata = "res://*/" + modelName + ".csdl" + "|" + ssdlOutputPath + "|res://*/" + modelName + ".msl", ProviderConnectionString = providerConnectionString }; return eBuilder.ToString(); } } 

2)修改创建ObjectContext的T4,以便它将使用ConnectionManager:

 public partial class MyModelUnitOfWork : ObjectContext { public const string ContainerName = "MyModelUnitOfWork"; public static readonly string ConnectionString = ConnectionManager.GetConnectionString("MyModel"); 

3)将以下行添加到App.Config:

 <?xml version =“1.0”encoding =“utf-8”?>
 <结构>
   节点
     
   节点
   <的appSettings>
     
     
   
 

ConnectionManager将ConnectionString和Provider替换为App.Config中的内容。

您可以对所有ObjectContexts使用相同的ConnectionManager(因此它们都从App.Config读取相同的设置),或编辑T4,以便为每个(在其自己的命名空间中)创建一个ConnectionManager,以便每个读取单独的设置。

我的理解是你想要相同的连接字符串,其中包含不同的元数据。 因此,您可以使用下面给出的连接字符串并替换“”部分。 我以相同的顺序使用了你给定的connectionString。

 connectionString="provider=System.Data.SqlClient;provider connection string="Data Source=SomeServer;Initial Catalog=SomeCatalog;Persist Security Info=True;User ID=Entity;Password=SomePassword;MultipleActiveResultSets=True"" 

对于第一个connectionString,将替换为"metadata=res://*/ModEntity.csdl|res://*/ModEntity.ssdl|res://*/ModEntity.msl;"

对于第二个connectionString,将替换为"metadata=res://*/Entity.csdl|res://*/Entity.ssdl|res://*/Entity.msl;"

对于第三个connectionString,将替换为"metadata=res://*/Entity.csdl|res://*/Entity.ssdl|res://*/Entity.msl|res://*/ModEntity.csdl|res://*/ModEntity.ssdl|res://*/ModEntity.msl;"

快乐的编码!

Silverlight应用程序无法直接访问machine.config。