mohamad_ali Ответов: 2

Как переключаться между некоторыми соединениями в MVC


привет , у меня есть некоторая база данных и работа с одним проектом mvc, и все базы данных одинаковы, и все пользователи регистрируются в этом формате( companyname/username)
когда пользователь хочет войти в систему я получаю базу данных и сохраняю ее в сеансе
и когда я хочу проверить, что пользователь действителен, я получаю ошибку:
System.ArgumentException: 'Keyword not supported: 'metadata'.'


Что я уже пробовал:

авторизоваться:

public ActionResult Login(LoginViewModel login, string ReturnUrl = "")
       {

           string input = login.username.Trim();

           int index = input.IndexOf("/");
           if (index > 0)
               input = input.Substring(0, index);





           if (input == "Pub")
           {
               Session["_DBNAME_"] = "database name";

           }


using (databaseEntities dbo = new databaseEntities(Session["_DBNAME_"].ToString()))
          {


------------------------------------------------------------
DbContext можно:

  public partial class databaseEntities : DbContext
    {
      

        public databaseEntities(string companyName)
      
        {
            string connString = ConfigurationManager.ConnectionStrings["databaseEntities"].ConnectionString;
            connString = connString.Replace("_DBNAME_", companyName);
            this.Database.Connection.ConnectionString = connString;

get error here:


        }



--------------------------------------------

webconfig:

 <connectionStrings>

<add name="databaseEntities" connectionString="metadata=res://*/Models.databaseModel.csdl|res://*/Models.databaseModel.ssdl|res://*/Models.databaseModel.msl;provider=System.Data.SqlClient;provider connection string="data source=.;initial catalog=_DBNAME_;user id=sa;password=pwd;multipleactiveresultsets=True;application name=EntityFramework"" providerName="System.Data.EntityClient" />

</connectionStrings>

2 Ответов

Рейтинг:
7

Maciej Los

Ты делаешь это неправильно...

#1
Если модель сущностей одинакова для каждой компании, вы должны определить столько соединений, сколько компаний (баз данных) вы создали:

<connectionStrings>
    <add name="CompanyA" providerName="..." connectionString="..." />
    <add name="CompanyB" providerName="..." connectionString="..." />
</connectionStrings>


Ваша сущность должна принимать строку подключения в качестве входного параметра:
namespace YourNameSpaceHere
{
    public class YourEntity: DbContext
    {
        private string connstring = string.Empty;
        public YourEntity(string _companyName) : base()
        {

            //get connection string by company name
            connstring = ConfigurationManager.ConnectionStrings[_companyName].ConnectionString;
        }


}


#2
Если модель сущностей между компаниями различна, вы должны определить разные сущности для каждой компании
public Company1Context()
            : base("Company1") // connection string key
        {
            //define options here
        }

public Company2Context()
            : base("Company2") // connection string key
        {
            //define options here
        }


mohamad_ali

thnx для ответа,но я хочу переключаться между некоторыми базами данных с одной строкой подключения , только имя базы данных replce

Maciej Los

Смотрите, решение №2

Рейтинг:
2

Maciej Los

mohamad_ali писал:

...я хочу переключаться между некоторыми базами данных с одной строкой подключения , только replce имя базы данных


Итак, создаем умолчанию-связи:
<connectionStrings>
    <add name="defaultconnection" providerName="System.Data.SqlClient"

        connectionString="Server=ServerName\InstanceName; Database=CompanyA;User Id=sa;Password=pwd;" />
</connectionStrings>



Итак, создайте connstring "по требованию"
namespace YourNameSpaceHere
{
    public class YourEntity: DbContext
    {
        private string connstring = string.Empty;
        public YourEntity(string _companyName) : base()
        {

            //get default connection string 
            connstring = ConfigurationManager.ConnectionStrings["defaultconnection"].ConnectionString;
            //returns:
            //"metadata=res://*/MyModel.csdl|res://*/MyModel.ssdl|res://*/MyModel.msl;data source=.;initial catalog=CompanyA;user id=sa;password=pwd;MultipleActiveResultSets=True;App=EntityFramework";
            Dictionary<string, string> connparts = GetConnParts(conn);
            connparts["initial catalog"] = _companyName;
            connstring = string.Join(";", connparts.Select(kvp=> $"{kvp.Key}={kvp.Value}"));
        }

	private Dictionary<string, string> GetConnParts(string sConnString)
	{
		return sConnString.Split(new string[]{";"}, StringSplitOptions.RemoveEmptyEntries)
			.Select(x=> new KeyValuePair<string, string>(x.Split('=')[0], x.Split('=')[1]))
			.ToDictionary(kvp=> kvp.Key, kvp=> kvp.Value);
	}


}


Обратите внимание, что этот метод не рекомендуется!


mohamad_ali

почему, и какой путь лучше?

Maciej Los

Лучший способ - определить столько строк подключения, сколько компаний, а затем получить строку подключения по названию компании;) - Решение № 1

mohamad_ali

thnx для guidng me, но когда соединение хочет opeen, я получил ошибку

System.Data.Entity.Infrastructure.UnintentionalCodeFirstException: 'The context is being used in Code First mode with code that was generated from an EDMX file for either Database First or Model First development. This will not work correctly. To fix this problem do not remove the line of code that throws this exception. If you wish to use Database First or Model First, then make sure that the Entity Framework connection string is included in the app.config or web.config of the start-up project. If you are creating your own DbConnection, then make sure that it is an EntityConnection and not some other type of DbConnection, and that you pass it to one of the base DbContext constructors that take a DbConnection. To learn more about Code First, Database First, and Model First see the Entity Framework documentation here: http://go.microsoft.com/fwlink/?LinkId=394715'

Maciej Los

ОК. Моя ошибка, потому что вы сначала не предоставили информацию о коде. Вы должны использовать свою строку подключения, а не мою. Используя метод GetConnParts, вы можете заново построить строку подключения.
[РЕДАКТИРОВАТЬ]
Смотрите обновленный ответ ;)

mohamad_ali

thnx много ,проблема была решена