#asp.net-mvc-3 #entity-framework-4 #ninject #mvc-mini-profiler
#asp.net-mvc-3 #entity-framework-4 #ninject #mvc-mini-profiler
Вопрос:
Я пытаюсь использовать новый mvc-mini-profiler с моим приложением на базе EF4, но я понятия не имею, как правильно установить соединение с моим конечным источником данных.
Вот все, что я получил.
Func<IMyContainer> createContainer = () =>
{
var profiler = MiniProfiler.Current;
if (profiler != null)
{
var rootConn = // ????
var conn = ProfiledDbConnection.Get(rootConn);
return ObjectContextUtils.CreateObjectContext<MyContainer>(conn);
}
else
{
return new MyContainer();
}
};
kernel.Bind<IMyContainer>().ToMethod(ctx => createContainer()).InRequestScope();
Как мне получить соединение с контейнером EF без самого contianer? Я бы просто обновил SqlConnection, за исключением того, что строка подключения завернута во весь мусор EF.
Комментарии:
1. Вы ищете
(MyObjectContext.Connection as EntityConnection).StoreConnection
?2. @Craig: Нет, потому что у меня
MyContainer
еще нет.
Ответ №1:
Немного менее хакерский способ:
private static SqlConnection GetConnection()
{
var connStr = ConfigurationManager.ConnectionStrings["ModelContainer"].ConnectionString;
var entityConnStr = new EntityConnectionStringBuilder(connStr);
return new SqlConnection(entityConnStr.ProviderConnectionString);
}
Поправка Джона Гитцена:
Эта комбинация всех ответов должна работать для ЛЮБОГО хранилища резервных копий, поддерживаемого Entity Framework.
public static DbConnection GetStoreConnection<T>() where T : System.Data.Objects.ObjectContext
{
return GetStoreConnection("name=" typeof(T).Name);
}
public static DbConnection GetStoreConnection(string entityConnectionString)
{
// Build the initial connection string.
var builder = new EntityConnectionStringBuilder(entityConnectionString);
// If the initial connection string refers to an entry in the configuration, load that as the builder.
object configName;
if (builder.TryGetValue("name", out configName))
{
var configEntry = WebConfigurationManager.ConnectionStrings[configName.ToString()];
builder = new EntityConnectionStringBuilder(configEntry.ConnectionString);
}
// Find the proper factory for the underlying connection.
var factory = DbProviderFactories.GetFactory(builder.Provider);
// Build the new connection.
DbConnection tempConnection = null;
try
{
tempConnection = factory.CreateConnection();
tempConnection.ConnectionString = builder.ProviderConnectionString;
var connection = tempConnection;
tempConnection = null;
return connection;
}
finally
{
// If creating of the connection failed, dispose the connection.
if (tempConnection != null)
{
tempConnection.Dispose();
}
}
}
Комментарии:
1. Это может быть лучшим на сегодняшний день. Есть ли способ «волшебным» образом определить, хотим ли мы использовать класс SqlConnection или… класс OracleConnection, например?
2. Строка подключения объекта имеет свойство Provider, поэтому вы могли бы использовать это в инструкции switch и создавать экземпляры соединения по-разному в зависимости от поставщика. Затем просто установите возвращаемый тип в DbConnection, и я думаю, у вас все получится.
3. Я нашел более элегантный способ, см.
DbProviderFactories
Класс.
Ответ №2:
Вот немного более производительное, но немного более хакерское решение для подключения к хранилищу.
public static DbConnection GetStoreConnection<T>() where T : System.Data.Objects.ObjectContext
{
return GetStoreConnection("name=" typeof(T).Name);
}
public static DbConnection GetStoreConnection(string entityConnectionString)
{
DbConnection storeConnection;
// Let entity framework do the heavy-lifting to create the connection.
using (var connection = new EntityConnection(entityConnectionString))
{
// Steal the connection that EF created.
storeConnection = connection.StoreConnection;
// Make EF forget about the connection that we stole (HACK!)
connection.GetType().GetField("_storeConnection",
BindingFlags.NonPublic | BindingFlags.Instance).SetValue(connection, null);
// Return our shiny, new connection.
return storeConnection;
}
}
Ответ №3:
Вы должны инициализировать соединение напрямую, как таковое:
var rootConn = new System.Data.SqlClient.SqlConnection(your_connection_string_minus_your_ef_junk);
Комментарии:
1. Это точно не говорит мне о «правильном» способе сделать это.
2. У меня это тоже отлично работает. Просто создайте SqlConnection и передайте его в ObjectContextUtils. Создайте ObjectContext<YourContextClass>(rootConn). Готово!
3. Отключите oraConn в качестве нового OracleConnection (Новый EntityConnectionStringBuilder(ConfigurationManager. Строки подключения («edmEntities»). Строка подключения). ProviderConnectionString)