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; }
    }