c#实体框架EF 4.1在运行时更改架构和数据库名称
本文关键字:数据库 运行时 框架 实体 EF | 更新日期: 2023-09-27 18:29:48
我搜索了一些主题,但没有找到解决问题的具体方法。
我的应用程序是一个c#商业应用程序。我首先使用EF 4.1数据库。我从一个开发数据库连接中生成了模型,并创建了一个model.edmx文件和所有EF文件。
我的目标是向客户提供应用程序,让他自己自由创建数据库和数据库用户。这样做,在运行时,我会获得用户名、密码、数据库连接和模式名称参数,以连接到客户数据库。这样,要部署应用程序,我只需要要求客户创建一个数据库,并将数据库参数添加到应用程序配置文件中。
因此,myy的目标是在运行时更改连接字符串和模式参数,而不更改所有自动生成的edmx文件,也不更改VS生成的代码。
我环顾四周,发现:
对于EF早期版本:
在运行时更改架构名称-实体框架
http://efmodeladapter.codeplex.com
所有其他帖子都围绕着这一点展开。我甚至试图使用第一个邮政编码,但没有成功。
但我看到EF 4.1提供了更好的支持工具,但我找不到它的参考或示例。重要的是不要更改VS的自动生成代码。
我是EF的新手,所以我想请求帮助完成以下任务:a) 在运行时更改连接字符串,添加我的用户名、密码和数据库服务器/端口参数b) 更改数据库架构
我使用Oracle作为数据库服务器(由于Oracle将模式和用户混合在一起,所以情况更糟)。
实际上,我也需要解决方案。我很快想出了解决方案,效果很好。我在互联网上找不到太多关于这方面的信息,所以我不确定"EF 4.1有更好的支持工具"。
具体的例子"在运行时更改模式名称-实体框架"对我来说并不完全有效,但经过一些小的修改,我使它发挥了作用。
这里有一个DatabaseUtils类可以做到这一点:
internal static class DatabaseUtils
{
/// <summary>
/// Builds the connection string for Entity framework.
/// </summary>
/// <returns></returns>
public static EntityConnection BuildConnection(BuildConnectionParams buildConnectionParams)
{
var sqlBuilder = new SqlConnectionStringBuilder
{
DataSource = buildConnectionParams.ServerName,
InitialCatalog = buildConnectionParams.DatabaseName,
IntegratedSecurity = true
};
var providerString = sqlBuilder.ToString();
var entityBuilder = new EntityConnectionStringBuilder
{
Provider = buildConnectionParams.ProviderName,
ProviderConnectionString = providerString,
Metadata = string.Format(@"res://*/{0}.csdl|
res://*/{0}.ssdl|
res://*/{0}.msl", buildConnectionParams.ModelName)
};
return CreateConnection(buildConnectionParams.SchemaName, entityBuilder, buildConnectionParams.ModelName);
}
/// <summary>
/// Creates the EntityConnection, based on new schema & existing connectionString
/// </summary>
/// <param name="schemaName">Name of the schema.</param>
/// <param name="connectionBuilder"></param>
/// <param name="modelName">Name of the model.</param>
/// <returns></returns>
private 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");
if (conceptualReader == null || mappingReader == null || storageReader == null)
{
disposeCollection(new[] { conceptualReader, mappingReader, storageReader });
return null;
}
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>
/// Initializes a new instance of the <see cref="DynamicAQDContext"/> class.
/// </summary>
public DynamicAQDContext()
{
var entityConnection = DatabaseUtils.BuildConnection(new BuildConnectionParams
{
ProviderName = "System.Data.SqlClient",
ServerName = "localhost''",
DatabaseName = "",
ModelName = "YOURMODEL",
SchemaName = "SCHEMA"
});
if(entityConnection == null)
throw new Exception("Can't create EntityConnection");
_entities = new LINKEntities(entityConnection);
}
更多信息可以在这里找到:http://bestplayah.com/entity-framework-dynamic-schema-changes-using-database-first-approach/