是否可以在运行时将数据库模式映射到构建动态EntityConnection?
我的下面有一个函数连接到我们的内部数据库,以返回必要的凭据:
public string GetEntityConnection(int? portalId)
{
const string providerName = "System.Data.SqlClient";
var entityBuilder = new EntityConnectionStringBuilder();
var portalConnections = _portalAdminEntities.Portal_connections.SingleOrDefault(m => m.Portal_ID == portalId);
if (portalConnections != null)
{
var sqlBuilder = new SqlConnectionStringBuilder
{
DataSource = portalConnections.PortalServer,
InitialCatalog = portalConnections.PortalDatabase,
UserID = portalConnections.PortalUsername,
Password = portalConnections.PortalPassword,
PersistSecurityInfo = true
};
var providerString = sqlBuilder.ToString();
entityBuilder = new EntityConnectionStringBuilder
{
Provider = providerName,
ProviderConnectionString = providerString,
Metadata = @"res://*/Models.PortalAdmin.csdl|res://*/Models.PortalAdmin.ssdl|res://*/Models.PortalAdmin.msl"
};
}
return entityBuilder.ToString();
}
然后我调用这样的函数将数据上传到我们的远程服务器:
using (var portalAdminEntities = new PortalAdminEntities(new EntityConnection(_df.GetEntityConnection(model.portalId))))
{
portalAdminEntities.InsertPageDetails(model.pageId, portalId, model.title, model.content);
}
尽管已成功连接到我们的远程服务器,但由于远程服务器上的数据库架构不同,无法找到实际的存储过程。
我认为该问题与Models.PortalAdmin.msl有关,因为此文件是由Visual Studio 2010在创建实体框架以连接到我们的内部数据库时生成的,因此存储了架构。在这种情况下,我们的内部架构为dbo
,而在外部我们使用somethingelse
(由我们的外部托管服务提供商控制)。
在连接执行远程任务时,是否可以绕过msl
文件或模式定义?
答案 0 :(得分:0)
我认为你不想绕过msl或任何生成的文件。您可以手动删除dbo。来自msl,ssdl和csdl,如果你想要或通过Ef模型属性,这意味着db将在任何环境中工作。
答案 1 :(得分:0)
进一步调查发现,Visual Studio 2010生成的csdl,msdl和ssdl文件需要在运行时导入并进行操作>我在下面的更新解决方案允许使用除dbo之外的模式在运行时创建动态实体连接:
public EntityConnection GetEntityConnection(int? portalId, string modelName)
{
var serverName = "";
var databaseName = "";
var username = "";
var password = "";
var portalConnections = _portalAdminEntities.Portal_connections.SingleOrDefault(m => m.Portal_ID == portalId);
if (portalConnections != null)
{
serverName = portalConnections.PortalServer;
databaseName = portalConnections.PortalDatabase;
username = portalConnections.PortalUsername;
password = portalConnections.PortalPassword;
}
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(databaseName);
}
}
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);
const string providerName = "System.Data.SqlClient";
var sqlBuilder = new SqlConnectionStringBuilder
{
DataSource = serverName,
InitialCatalog = databaseName,
UserID = username,
Password = password,
PersistSecurityInfo = true
};
var providerString = sqlBuilder.ToString();
var entityBuilder = new EntityConnectionStringBuilder
{
Provider = providerName,
ProviderConnectionString = providerString,
Metadata = string.Format(@"res://*/{0}.csdl|res://*/{0}.ssdl|res://*/{0}.msl", modelName)
};
var connection = DbProviderFactories.GetFactory(entityBuilder.Provider).CreateConnection();
if (connection == null)
{
disposeCollection(new[] { conceptualReader, mappingReader, storageReader });
return null;
}
connection.ConnectionString = entityBuilder.ProviderConnectionString;
return new EntityConnection(workspace, connection);
}
using (var portalAdminEntities = new PortalAdminEntities(_df.GetEntityConnection(model.Portal_ID, Models.PortalAdmin")))
{
portalAdminEntities.InsertPageDetails(model.pageId, portalId, model.title, model.content);
}
我希望这对其他人有用: - )