Entity Framework 6 устанавливает строку подключения в коде
У меня есть dll, которая использует Entity Framework 6 для выполнения некоторых операций с базой данных. Я использую первый подход к базе данных.
Модель и все, что касается Entity Framework, как и строка подключения в App.config, были созданы с помощью wizzard в Visual Studio.
Итак, я скомпилировал dll и поместил его вместе с соответствующим .config в папку, в которой ожидает приложение, использующее dll.
Все работает нормально, пока не дойду до того момента, когда будет выполнен фактический вызов базы данных. Там я получаю сообщение об ошибке:
Не удается найти строку подключения для MyDatabaseEntity
Сгенерированная автоматически строка соединения, как я уже сказал, является файлом конфигурации DLL. Я не могу изменить App.config приложения.
Но приложение передает объект, у которого есть вся информация, необходимая мне для сборки строки подключения.
Поэтому я ищу способ установить строку соединения в коде, не полагаясь на файл конфигурации.
Однако все учебники, которые я нахожу для первого подхода к базе данных, используют этот метод.
Я нашел здесь сообщение, в котором говорится просто указать строку соединения в качестве параметра при создании объекта типа
MyDatabaseEntities = new MyDatabaseEntities(dbConnect);
но'MyDatabaseEntities 'не имеет конструктора, который принимает любые параметры
public partial class MyDatabaseEntities : DbContext
{
public MyDatabaseEntities()
: base("name=MyDatabaseEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<MyTable> MyTable { get; set; }
}
Ответы
Ответ 1
Как насчет:
public partial class MyDatabaseEntities : DbContext
{
public MyDatabaseEntities(string connectionString)
: base(connectionString)
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<MyTable> MyTable { get; set; }
}
Затем выполните инициализацию своей базы данных, как вы это делали раньше:
string myConnectionString = "...";
MyDatabaseEntities = new MyDatabaseEntities(myConnectionString);
Ответ 2
Я получил это решение, используя нижеприведенный код, я могу жестко скопировать строку соединения с использованием кода С# без использования файла конфигурации.
public class SingleConnection
{
private SingleConnection() { }
private static SingleConnection _ConsString = null;
private String _String = null;
public static string ConString
{
get
{
if (_ConsString == null)
{
_ConsString = new SingleConnection { _String = SingleConnection.Connect() };
return _ConsString._String;
}
else
return _ConsString._String;
}
}
public static string Connect()
{
//Build an SQL connection string
SqlConnectionStringBuilder sqlString = new SqlConnectionStringBuilder()
{
DataSource = "SIPL35\\SQL2016".ToString(), // Server name
InitialCatalog = "Join8ShopDB", //Database
UserID = "Sa", //Username
Password = "[email protected]#", //Password
};
//Build an Entity Framework connection string
EntityConnectionStringBuilder entityString = new EntityConnectionStringBuilder()
{
Provider = "System.Data.SqlClient",
Metadata = "res://*/ShopModel.csdl|res://*/ShopModel.ssdl|res://*/ShopModel.msl",
ProviderConnectionString = @"data source=SIPL35\SQL2016;initial catalog=Join8ShopDB2;user id=Sa;[email protected]#;"// sqlString.ToString()
};
return entityString.ConnectionString;
}
и используя DbContext, используя следующее:
Join8ShopDBEntities dbContext = new Join8ShopDBEntities(SingleConnection.ConString);
Ответ 3
У меня была аналогичная проблема. Мой Edmx и App.Config были в другом проекте. Мой проект запуска был другим, имел 3 разных строки подключения, нам нужно выбрать один на лету в зависимости от среды. Поэтому не удалось использовать фиксированную строку соединения. Я создал частичную перегрузку класса Context.cs, используя одно и то же пространство имен. Следующим был мой default Context.cs;
namespace CW.Repository.DBModel
{
public partial class CWEntities : DbContext
{
public CWEntities()
: base("name=CWEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
...
...
}
}
Моя частичная перезагрузка класса;
namespace CW.Repository.DBModel
{
public partial class CWEntities : DbContext
{
public CWEntities(string ConnectionString)
: base(ConnectionString)
{
}
}
}
Наконец, поскольку мои строки подключения не были для EF, я преобразовал их в строку подключения EF.
public static string GetEntityConnectionString(string connectionString)
{
var entityBuilder = new EntityConnectionStringBuilder();
// WARNING
// Check app config and set the appropriate DBModel
entityBuilder.Provider = "System.Data.SqlClient";
entityBuilder.ProviderConnectionString = connectionString + ";MultipleActiveResultSets=True;App=EntityFramework;";
entityBuilder.Metadata = @"res://*/DBModel.CWDB.csdl|res://*/DBModel.CWDB.ssdl|res://*/DBModel.CWDB.msl";
return entityBuilder.ToString();
}
Наконец, вызов
var Entity = new CWEntities(CWUtilities.GetEntityConnectionString(ConnectionString));
Ответ 4
Большое спасибо. Я немного изменился для Code First EF6.
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.Entity.Core.EntityClient;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Data
{
public class SingleConnection
{
private SingleConnection() { }
private static SingleConnection _ConsString = null;
private String _String = null;
public static string ConString
{
get
{
if (_ConsString == null)
{
_ConsString = new SingleConnection { _String = SingleConnection.Connect() };
return _ConsString._String;
}
else
return _ConsString._String;
}
}
public static string Connect()
{
string conString = ConfigurationManager.ConnectionStrings["YourConnectionStringsName"].ConnectionString;
if (conString.ToLower().StartsWith("metadata="))
{
System.Data.Entity.Core.EntityClient.EntityConnectionStringBuilder efBuilder = new System.Data.Entity.Core.EntityClient.EntityConnectionStringBuilder(conString);
conString = efBuilder.ProviderConnectionString;
}
SqlConnectionStringBuilder cns = new SqlConnectionStringBuilder(conString);
string dataSource = cns.DataSource;
SqlConnectionStringBuilder sqlString = new SqlConnectionStringBuilder()
{
DataSource = cns.DataSource, // Server name
InitialCatalog = cns.InitialCatalog, //Database
UserID = cns.UserID, //Username
Password = cns.Password, //Password,
MultipleActiveResultSets = true,
ApplicationName = "EntityFramework",
};
//Build an Entity Framework connection string
EntityConnectionStringBuilder entityString = new EntityConnectionStringBuilder()
{
Provider = "System.Data.SqlClient",
Metadata = "res://*",
ProviderConnectionString = sqlString.ToString()
};
return entityString.ConnectionString;
}
}
}
Ответ 5
Вы можете использовать одноэлементную скороговорку для этого. Например,
private YouurDBContext context;
public YouurDBContext Context
{
get
{
if (context==null)
{
context = new YouurDBContext();
}
return context;
}
set { context = value; }
}