asp.net asp.net-mvc asp.net-core asp.net-identity entity-framework-core

ASP.NET Core cambia la cadena de conexión EF cuando el usuario inicia sesión



asp.net-mvc asp.net-core (6)

Después de algunas horas de investigación y de no encontrar la manera de hacerlo; Es hora de hacer la pregunta.

Tengo un proyecto ASP.NET Core 1.1 con EF Core y MVC que utilizan varios clientes. Cada cliente tiene su propia base de datos con el mismo esquema exacto. Este proyecto es actualmente una aplicación de Windows que se está migrando a la web. En la pantalla de inicio de sesión, el usuario tiene tres campos: Código de empresa, Nombre de usuario y Contraseña. Necesito poder cambiar la cadena de conexión cuando el usuario intenta iniciar sesión en función de lo que escribe en la entrada del Código de la empresa y luego recordar su entrada durante toda la sesión.

Encontré algunas formas de hacer esto con una base de datos y un esquema múltiple, pero ninguna con múltiples bases de datos que usan el mismo esquema.

La forma en que resolví este problema no es una solución real al problema, sino una solución que funcionó para mí. Mis bases de datos y mi aplicación están alojadas en Azure. Mi solución a esto fue actualizar mi servicio de aplicaciones a un plan que admite máquinas tragamonedas (solo $ 20 adicionales al mes por 5 máquinas tragamonedas). Cada ranura tiene el mismo programa, pero la variable de entorno que contiene la cadena de conexión es específica de la compañía. De esta manera, también puedo subdominio al que acceden las empresas si lo deseo. Si bien este enfoque puede no ser lo que otros harían, fue el más rentable para mí. Es más fácil publicar en cada ranura que pasar las horas haciendo la otra programación que no funciona correctamente. Hasta que Microsoft facilite cambiar la cadena de conexión, esta es mi solución.

En respuesta a la respuesta de Herzl

Esto parece que podría funcionar. He tratado de implementarlo. Sin embargo, una cosa que estoy haciendo es usar una clase de repositorio que accede a mi contexto. Mis controladores obtienen el repositorio inyectado en ellos para llamar a métodos en el repositorio que acceden al contexto. ¿Cómo hago esto en una clase de repositorio? No hay sobrecarga de OnActionExecuting en mi repositorio. Además, si esto persiste durante la sesión, ¿qué sucede cuando un usuario abre nuevamente su navegador a la aplicación y aún está conectado con una cookie que dura 7 días? ¿No es esta una nueva sesión? Parece que la aplicación arrojaría una excepción porque la variable de sesión sería nula y, por lo tanto, no tendría una cadena de conexión completa. Supongo que también podría almacenarlo como un Reclamo y usar el Reclamo si la variable de sesión es nula.

Aquí está mi clase de repositorio. IDbContextService fue ProgramContext pero comencé a agregar sus sugerencias para intentar que funcione.

public class ProjectRepository : IProjectRepository { private IDbContextService _context; private ILogger<ProjectRepository> _logger; private UserManager<ApplicationUser> _userManager; public ProjectRepository(IDbContextService context, ILogger<ProjectRepository> logger, UserManager<ApplicationUser> userManger) { _context = context; _logger = logger; _userManager = userManger; } public async Task<bool> SaveChangesAsync() { return (await _context.SaveChangesAsync()) > 0; } }

En respuesta a la respuesta de The Force JB

Traté de implementar tu enfoque. Me sale una excepción en Program.cs en línea

host.Run();

Aquí está mi clase ''Program.cs''. Sin tocar

using System.IO; using Microsoft.AspNetCore.Hosting; namespace Project { public class Program { public static void Main(string[] args) { var host = new WebHostBuilder() .UseKestrel() .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() .UseStartup<Startup>() .Build(); host.Run(); } } }

Y mi clase ''Startup.cs''.

using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Newtonsoft.Json.Serialization; using System; using System.Collections.Generic; using Project.Entities; using Project.Services; namespace Project { public class Startup { private IConfigurationRoot _config; public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json") .AddEnvironmentVariables(); _config = builder.Build(); } public void ConfigureServices(IServiceCollection services) { services.AddSingleton(_config); services.AddIdentity<ApplicationUser, IdentityRole>(config => { config.User.RequireUniqueEmail = true; config.Password.RequireDigit = true; config.Password.RequireLowercase = true; config.Password.RequireUppercase = true; config.Password.RequireNonAlphanumeric = false; config.Password.RequiredLength = 8; config.Cookies.ApplicationCookie.LoginPath = "/Auth/Login"; config.Cookies.ApplicationCookie.ExpireTimeSpan = new TimeSpan(7, 0, 0, 0); // Cookies last 7 days }) .AddEntityFrameworkStores<ProjectContext>(); services.AddScoped<IUserClaimsPrincipalFactory<ApplicationUser>, AppClaimsPrincipalFactory>(); services.AddScoped<IProjectRepository, ProjectRepository>(); services.AddTransient<MiscService>(); services.AddLogging(); services.AddMvc() .AddJsonOptions(config => { config.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); }); } public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) { Dictionary<string, string> connStrs = new Dictionary<string, string>(); connStrs.Add("company1", "1stconnectionstring")); connStrs.Add("company2", "2ndconnectionstring"; DbContextFactory.SetDConnectionString(connStrs); //app.UseDefaultFiles(); app.UseStaticFiles(); app.UseIdentity(); app.UseMvc(config => { config.MapRoute( name: "Default", template: "{controller}/{action}/{id?}", defaults: new { controller = "Auth", action = "Login" } ); }); } } }

Y la excepción:

InvalidOperationException: Unable to resolve service for type ''Project.Entities.ProjectContext'' while attempting to activate ''Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`4[Project.Entities.ApplicationUser,Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole,Project.Entities.ProjectContext,System.String]''.

No estoy seguro de qué hacer aquí.

Éxito parcial editar

Bien, tengo tu ejemplo funcionando. Puedo establecer la cadena de conexión en mi constructor de repositorio usando una identificación diferente. Mi problema ahora es iniciar sesión y elegir la base de datos correcta. Pensé en hacer que el repositorio se extrajera de una sesión o reclamo, lo que no fuera nulo. Pero no puedo establecer el valor antes de usar SignInManager en el controlador de inicio de sesión porque SignInManager se inyecta en el controlador que crea un contexto antes de actualizar la variable de sesión. La única forma en que puedo pensar es tener un inicio de sesión de dos páginas. La primera página solicitará el código de la empresa y actualizará la variable de sesión. La segunda página usará SignInManager y tendrá el repositorio inyectado en el constructor de controladores. Esto sucedería después de que la primera página actualice la variable de sesión. En realidad, esto puede ser más atractivo visualmente con animaciones entre ambas vistas de inicio de sesión. A menos que alguien tenga alguna idea sobre cómo hacer esto sin dos vistas de inicio de sesión, intentaré implementar el inicio de sesión de dos páginas y publicar el código si funciona.

En realidad está roto

Cuando funcionaba, es porque todavía tenía una cookie válida. Ejecutaría el proyecto y omitiría el inicio de sesión. Ahora recibo la excepción InvalidOperationException: No database provider has been configured for this DbContext después de borrar mi caché. Lo he revisado todo y el contexto se está creando correctamente. Supongo que Identity está teniendo algún tipo de problema. ¿Podría el siguiente código agregar las tiendas de framework de entidad en ConfigureServices estar causando el problema?

services.AddIdentity<ApplicationUser, IdentityRole>(config => { config.User.RequireUniqueEmail = true; config.Password.RequireDigit = true; config.Password.RequireLowercase = true; config.Password.RequireUppercase = true; config.Password.RequireNonAlphanumeric = false; config.Password.RequiredLength = 8; config.Cookies.ApplicationCookie.LoginPath = "/Company/Login"; config.Cookies.ApplicationCookie.ExpireTimeSpan = new TimeSpan(7, 0, 0, 0); // Cookies last 7 days }) .AddEntityFrameworkStores<ProgramContext>();

Editar

Verifiqué que la Identity es el problema. Saqué datos de mi repositorio antes de ejecutar PasswordSignInAsync y sacó los datos muy bien. ¿Cómo se crea el DbContext para Identity?


Crear una fábrica de DbContext

public static class DbContextFactory { public static Dictionary<string, string> ConnectionStrings { get; set; } public static void SetConnectionString(Dictionary<string, string> connStrs) { ConnectionStrings = connStrs; } public static MyDbContext Create(string connid) { if (!string.IsNullOrEmpty(connid)) { var connStr = ConnectionStrings[connid]; var optionsBuilder = new DbContextOptionsBuilder<MyDbContext>(); optionsBuilder.UseSqlServer(connStr); return new MyDbContext(optionsBuilder.Options); } else { throw new ArgumentNullException("ConnectionId"); } } }

Intialize DbContext factory

En startup.cs

public void Configure() { Dictionary<string, string> connStrs = new Dictionary<string, string>(); connStrs.Add("DB1", Configuration["Data:DB1Connection:ConnectionString"]); connStrs.Add("DB2", Configuration["Data:DB2Connection:ConnectionString"]); DbContextFactory.SetConnectionString(connStrs); }

Uso

var dbContext= DbContextFactory.Create("DB1");


Como está creando una aplicación web multiinquilino, primero debe decidir cómo distinguirá entre los inquilinos. ¿Vas a usar una URL diferente? o tal vez la misma URL pero agregando una parte en la URL?

Suponiendo que eligió este último, el inquilino 1 tendría una URL similar a esta: http://localhost:9090/tenant1/orders

El inquilino 2 tendría una URL como: http://localhost:9090/tenant2/orders

Puede hacerlo utilizando el enrutamiento de URL:

routes.MapRoute( name: "Multitenant", url: "{tenant}/{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } );

En cuanto a la cadena de conexión, necesita una clase para decidir la cadena de conexión en función de la URL e inyectar esta clase en el contexto de la base de datos.

public interface ITenantIdentifier { string GetCurrentTenantId(); } public class UrlTenantIdentifier : ITenantIdentifier { public string GetCurrentTenantId() { //Get the current Http Context and get the URL, you should have a table or configration that maps the URL to the tenant ID and connection string } }

En su contexto de base de datos:

public class MyDbContext: DbContext { public MyDbContext(ITenantIdentifier tenantIdentifier) { var connectionStringName = "TenantConnectionString"+tenantIdentifier.GetCurrentTenantId(); //here assuming that you are following a pattern, each tenant has a connection string in the shape of TenantConnectionString+ID var connectionString = //get connection string base(connectionString); } }


De acuerdo con su pregunta, voy a proporcionar una solución asumiendo algunas cosas:

Primero, he creado tres bases de datos en mi instancia local de SQL Server:

create database CompanyFoo go create database CompanyBar go create database CompanyZaz go

Luego, voy a crear una tabla con una fila en cada base de datos:

use CompanyFoo go drop table ConfigurationValue go create table ConfigurationValue ( Id int not null identity(1, 1), Name varchar(255) not null, [Desc] varchar(max) not null ) go insert into ConfigurationValue values (''Company name'', ''Foo Company'') go use CompanyBar go drop table ConfigurationValue go create table ConfigurationValue ( Id int not null identity(1, 1), Name varchar(255) not null, [Desc] varchar(max) not null ) go insert into ConfigurationValue values (''Company name'', ''Bar Company'') go use CompanyZaz go drop table ConfigurationValue go create table ConfigurationValue ( Id int not null identity(1, 1), Name varchar(255) not null, [Desc] varchar(max) not null ) go insert into ConfigurationValue values (''Company name'', ''Zaz Company'') go

El siguiente paso es crear un usuario con autenticación SQL y otorgar acceso para leer las bases de datos, en mi caso, mi nombre de usuario es johnd y la contraseña es 123.

Una vez que hemos completado estos pasos, procedemos a crear una aplicación MVC en ASP.NET Core, utilicé MultipleCompany como nombre del proyecto, tengo dos controladores: Inicio y Administración, el objetivo es mostrar primero una vista de inicio de sesión y luego redirigir a otra Ver para mostrar los datos de acuerdo con la base de datos seleccionada en la vista "Iniciar sesión"

Para cumplir con su requisito, necesitará usar la sesión en la aplicación ASP.NET Core, puede cambiar esta forma a almacenamiento y leer datos más tarde, por ahora esto es solo para prueba de concepto.

Código de HomeController:

using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using MultipleCompany.Models; namespace MultipleCompany.Controllers { public class HomeController : Controller { public IActionResult Index() { return View(); } [HttpPost] public IActionResult Index(LoginModel model) { HttpContext.Session.SetString("CompanyCode", model.CompanyCode); HttpContext.Session.SetString("UserName", model.UserName); HttpContext.Session.SetString("Password", model.Password); return RedirectToAction("Index", "Administration"); } public IActionResult Error() { return View(); } } }

Administración Código de controlador:

using System.Linq; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using MultipleCompany.Models; using MultipleCompany.Services; namespace MultipleCompany.Controllers { public class AdministrationController : Controller { protected IDbContextService DbContextService; protected CompanyDbContext DbContext; public AdministrationController(IDbContextService dbContextService) { DbContextService = dbContextService; } public override void OnActionExecuting(ActionExecutingContext context) { DbContext = DbContextService.CreateCompanyDbContext(HttpContext.Session.CreateLoginModelFromSession()); base.OnActionExecuting(context); } public IActionResult Index() { var model = DbContext.ConfigurationValue.ToList(); return View(model); } } }

Código para la vista de inicio:

@{ ViewData["Title"] = "Home Page"; } <form action="/home" method="post"> <fieldset> <legend>Log in</legend> <div> <label for="CompanyCode">Company code</label> <select name="CompanyCode"> <option value="CompanyFoo">Foo</option> <option value="CompanyBar">Bar</option> <option value="CompanyZaz">Zaz</option> </select> </div> <div> <label for="UserName">User name</label> <input type="text" name="UserName" /> </div> <div> <label for="Password">Password</label> <input type="password" name="Password" /> </div> <button type="submit">Log in</button> </fieldset> </form>

Código para la vista de Administración:

@{ ViewData["Title"] = "Home Page"; } <h1>Welcome!</h1> <table class="table"> <tr> <th>Name</th> <th>Desc</th> </tr> @foreach (var item in Model) { <tr> <td>@item.Name</td> <td>@item.Desc</td> </tr> } </table>

Código de modelo:

using System; using Microsoft.AspNetCore.Http; namespace MultipleCompany.Models { public class LoginModel { public String CompanyCode { get; set; } public String UserName { get; set; } public String Password { get; set; } } public static class LoginModelExtensions { public static LoginModel CreateLoginModelFromSession(this ISession session) { var companyCode = session.GetString("CompanyCode"); var userName = session.GetString("UserName"); var password = session.GetString("Password"); return new LoginModel { CompanyCode = companyCode, UserName = userName, Password = password }; } } }

Código CompanyDbContext:

using System; using Microsoft.EntityFrameworkCore; namespace MultipleCompany.Models { public class CompanyDbContext : Microsoft.EntityFrameworkCore.DbContext { public CompanyDbContext(String connectionString) { ConnectionString = connectionString; } public String ConnectionString { get; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer(ConnectionString); base.OnConfiguring(optionsBuilder); } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); } public DbSet<ConfigurationValue> ConfigurationValue { get; set; } } }

Código de valor de configuración:

using System; namespace MultipleCompany.Models { public class ConfigurationValue { public Int32? Id { get; set; } public String Name { get; set; } public String Desc { get; set; } } }

Código de configuración de la aplicación:

using System; namespace MultipleCompany.Models { public class AppSettings { public String CompanyConnectionString { get; set; } } }

Código IDbContextService:

using MultipleCompany.Models; namespace MultipleCompany.Services { public interface IDbContextService { CompanyDbContext CreateCompanyDbContext(LoginModel model); } }

Código DbContextService:

using System; using Microsoft.Extensions.Options; using MultipleCompany.Models; namespace MultipleCompany.Services { public class DbContextService : IDbContextService { public DbContextService(IOptions<AppSettings> appSettings) { ConnectionString = appSettings.Value.CompanyConnectionString; } public String ConnectionString { get; } public CompanyDbContext CreateCompanyDbContext(LoginModel model) { var connectionString = ConnectionString.Replace("{database}", model.CompanyCode).Replace("{user id}", model.UserName).Replace("{password}", model.Password); var dbContext = new CompanyDbContext(connectionString); return dbContext; } } }

Código de inicio:

using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using MultipleCompany.Models; using MultipleCompany.Services; namespace MultipleCompany { public class Startup { public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) .AddEnvironmentVariables(); Configuration = builder.Build(); } public IConfigurationRoot Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddMvc(); services.AddEntityFrameworkSqlServer().AddDbContext<CompanyDbContext>(); services.AddScoped<IDbContextService, DbContextService>(); services.AddDistributedMemoryCache(); services.AddSession(); services.AddOptions(); services.Configure<AppSettings>(Configuration.GetSection("AppSettings")); services.AddSingleton<IConfiguration>(Configuration); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseBrowserLink(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseSession(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); } } }

He agregado estos paquetes para mi proyecto:

"Microsoft.EntityFrameworkCore": "1.0.1", "Microsoft.EntityFrameworkCore.SqlServer": "1.0.1", "Microsoft.AspNetCore.Session": "1.0.0"

Mi archivo appsettings.json:

{ "Logging": { "IncludeScopes": false, "LogLevel": { "Default": "Debug", "System": "Information", "Microsoft": "Information" } }, "AppSettings": { "CompanyConnectionString": "server=(local);database={database};user id={user id};password={password}" } }

Por favor, concéntrese en el concepto de conectarse a la base de datos seleccionada en la vista de inicio, puede cambiar cualquier parte de este código como una mejora, recuerde que estoy proporcionando esta solución haciendo algunas suposiciones de acuerdo con su breve pregunta, no dude en preguntar sobre cualquier aspecto expuesto en esta solución para mejorar este fragmento de código de acuerdo con sus requisitos.

Básicamente, necesitamos definir un servicio para crear la instancia del contexto db de acuerdo con la base de datos seleccionada, esa es la interfaz IDbContextService y DbContextService es la implementación para esa interfaz.

Como puede ver en el código DbContextService, reemplazamos los valores dentro de {} para crear una cadena de conexión diferente, en este caso he agregado los nombres de la base de datos en la lista desplegable, pero en el desarrollo real, evite de esta manera porque por razones de seguridad es mejor para no exponer los nombres reales de sus bases de datos y otras configuraciones; puede tener una tabla de paridad del lado del controlador para resolver el código de la compañía de acuerdo con la base de datos seleccionada.

Una mejora para esta solución, sería agregar algún código para serializar el modelo de inicio de sesión como json en la sesión en lugar de almacenar cada valor de forma separada.

Avíseme si esta respuesta es útil. PD: Avíseme en los comentarios si desea cargar el código completo en una unidad


Encontraste tu respuesta, pero tal vez mi publicación puede ser útil para alguien. Tuve un problema similar como esta pregunta. Tuve que cambiar la cadena de conexiones del marco de mi entidad para conectar un servidor de base de datos diferente después de que el usuario inició sesión. Y para solucionarlo, eliminé esta función de mi clase de contexto

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { if (!optionsBuilder.IsConfigured) { #warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings. optionsBuilder.UseSqlServer("your connectionstring..."); }

porque no pude llamar a esta función desde afuera. Y tuve este constructor autogenerado

public ClientContext(DbContextOptions<ClientContext> options) : base(options) { }

Después de la eliminación, agregué este código a mi clase de contexto.

public ClientContext CreateConnectionFromOut(string connectionString) { var optionsBuilder = new DbContextOptionsBuilder<Esdesk_ClientContext>(); optionsBuilder.UseSqlServer(connectionString); var context = new ClientContext(optionsBuilder.Options); return context; }

Ahora, finalmente, puedo cambiar mi cadena de conexión desde donde quiera. Es así

ClientContext cc = new ClientContext(); var db = cc.CreateConnectionFromOut("your connection string");

Espero que esto pueda estar bien para alguien.


Puede intentar lo siguiente mientras crea su instancia de contexto:

// in class DBHelper public static YourEntities GetDbContext(string tenantName) { var connectionStringTemplate = @"metadata=res://*/yourModel.csdl|res://*/yourModel.ssdl|res://*/yourModel.msl;" + @"provider=System.Data.SqlClient;" + @"provider connection string=""data source=.;" + @"initial catalog={0};" + @"user id=sa;password=pwd;" + @"MultipleActiveResultSets=True;App=EntityFramework"";"; var connectionString = string.Format(connection, tenantName); var db = new YourEntities(connectionString); return db; }

Luego haga un constructor en su clase de contexto que acepte la cadena como parámetro y úselo como:

var db = DBHelper.GetDbContext(name of database to connect);


Actualizar para pasar la cadena de conexión

Para pasar la conexión generada dinámicamente a su contexto, cree una clase parcial en el mismo contexto que su clase de contexto parcial aseguraría que permanezca intacta si alguien ejecuta la herramienta personalizada (para edmx), el código generado automáticamente será eliminado y regenerado . Si tiene este código en una clase parcial, no se eliminará. Para el código primero, esto no se aplicará. Aquí está el código:

public class YourContext : DbContext { public YourContext(string connString) { } }

La forma en que lo hice en el pasado es tener una base de datos donde se almacenan las cuentas (nombres de usuario, contraseñas) de todos los clientes. La cuenta con la que se ejecuta la aplicación se usaría para comunicarse con esta base de datos para autenticar al cliente que está iniciando sesión (ID de empresa, contraseña).

Luego, una vez autenticado, se genera un token. Posteriormente, el usuario autenticado estará interactuando con la base de datos de ese cliente (Compañía). Para esta parte, puede crear la conexión sobre la marcha como se muestra here pero también la copiaré y pegaré:

// Specify the provider name, server and database. string providerName = "System.Data.SqlClient"; string serverName = "."; string databaseName = "AdventureWorks"; // Initialize the connection string builder for the // underlying provider. SqlConnectionStringBuilder sqlBuilder = new SqlConnectionStringBuilder(); // Set the properties for the data source. sqlBuilder.DataSource = serverName; sqlBuilder.InitialCatalog = databaseName; sqlBuilder.IntegratedSecurity = true; // Build the SqlConnection connection string. string providerString = sqlBuilder.ToString(); // Initialize the EntityConnectionStringBuilder. EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder(); //Set the provider name. entityBuilder.Provider = providerName; // Set the provider-specific connection string. entityBuilder.ProviderConnectionString = providerString; // Set the Metadata location. entityBuilder.Metadata = @"res://*/AdventureWorksModel.csdl| res://*/AdventureWorksModel.ssdl| res://*/AdventureWorksModel.msl"; Console.WriteLine(entityBuilder.ToString());

Deberá proporcionar sus propios nombres csdl, ssdl y msl en el código anterior. Si está utilizando Code First, su cadena de conexión no necesitará los metadatos.