استفاده از چندین بانک اطلاعاتی به صورت همزمان در EF Code First
نویسنده: وحید نصیری
تاریخ: ۱۳۹۳/۱۲/۱۰ ۱۳:۰
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
<connectionStrings> <clear /> <add name="Sample07Context" connectionString="Data Source=(local);Initial Catalog=TestDbIoC;Integrated Security = true" providerName="System.Data.SqlClient" /> <add name="Database2012" connectionString="Data Source=(local);Initial Catalog=testdb2012;Integrated Security = true" providerName="System.Data.SqlClient" /> </connectionStrings>
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using EF_Sample07.DomainClasses;
namespace EF_Sample07.DataLayer.Context
{
public class Sample07Context : DbContext, IUnitOfWork
{
public DbSet<Category> Categories { set; get; }
public DbSet<Product> Products { set; get; }
/// <summary>
/// It looks for a connection string named Sample07Context in the web.config file.
/// </summary>
public Sample07Context()
: base("Sample07Context")
{
}
/// <summary>
/// To change the connection string at runtime. See the SmObjectFactory class for more info.
/// </summary>
public Sample07Context(string connectionString)
: base(connectionString)
{
//Note: defaultConnectionFactory in the web.config file should be set.
}
public void SetConnectionString(string connectionString)
{
this.Database.Connection.ConnectionString = connectionString;
}
}
} using System;
using System.Threading;
using System.Web;
using EF_Sample07.DataLayer.Context;
using EF_Sample07.ServiceLayer;
using StructureMap;
using StructureMap.Web;
using StructureMap.Web.Pipeline;
namespace EF_Sample07.IoCConfig
{
public static class SmObjectFactory
{
private static readonly Lazy<Container> _containerBuilder =
new Lazy<Container>(defaultContainer, LazyThreadSafetyMode.ExecutionAndPublication);
public static IContainer Container
{
get { return _containerBuilder.Value; }
}
public static void HttpContextDisposeAndClearAll()
{
HttpContextLifecycle.DisposeAndClearAll();
}
private static Container defaultContainer()
{
return new Container(ioc =>
{
// session manager setup
ioc.For<ISessionProvider>().Use<DefaultWebSessionProvider>();
ioc.For<HttpSessionStateBase>()
.Use(ctx => new HttpSessionStateWrapper(HttpContext.Current.Session));
ioc.For<IUnitOfWork>()
.HybridHttpOrThreadLocalScoped()
.Use<Sample07Context>()
// Remove these 2 lines if you want to use a connection string named Sample07Context, defined in the web.config file.
.Ctor<string>("connectionString")
.Is(ctx => getCurrentConnectionString(ctx));
ioc.For<ICategoryService>().Use<EfCategoryService>();
ioc.For<IProductService>().Use<EfProductService>();
ioc.For<ICategoryService>().Use<EfCategoryService>();
ioc.For<IProductService>().Use<EfProductService>();
ioc.Policies.SetAllProperties(properties =>
{
properties.OfType<IUnitOfWork>();
properties.OfType<ICategoryService>();
properties.OfType<IProductService>();
properties.OfType<ISessionProvider>();
});
});
}
private static string getCurrentConnectionString(IContext ctx)
{
if (HttpContext.Current != null)
{
// this is a web application
var sessionProvider = ctx.GetInstance<ISessionProvider>();
var connectionString = sessionProvider.Get<string>("CurrentConnectionString");
if (string.IsNullOrWhiteSpace(connectionString))
{
// It's a default connectionString.
connectionString = "Database2012";
// this session value should be set during the login phase
sessionProvider.Store("CurrentConnectionStringName", connectionString);
}
return connectionString;
}
else
{
// this is a desktop application, so you can store this value in a global static variable.
return "Database2012";
}
}
}
} sessionProvider.Store("CurrentConnectionString", "Sample07Context");
uow.SetConnectionString(WebConfigurationManager.ConnectionStrings[_sessionProvider.Get<string>("CurrentConnectionString")].ConnectionString); using System;
using System.Data.Entity;
using System.Web;
using EF_Sample07.DataLayer.Context;
using EF_Sample07.IoCConfig;
namespace EF_Sample07.WebFormsAppSample
{
public class Global : HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
initDatabases();
}
private static void initDatabases()
{
// defined in web.config
string[] connectionStringNames =
{
"Sample07Context",
"Database2012"
};
foreach (var connectionStringName in connectionStringNames)
{
Database.SetInitializer(
new MigrateDatabaseToLatestVersion<Sample07Context, Configuration>(connectionStringName));
using (var ctx = new Sample07Context(connectionStringName))
{
ctx.Database.Initialize(force: true);
}
}
}
void Application_EndRequest(object sender, EventArgs e)
{
SmObjectFactory.HttpContextDisposeAndClearAll();
}
}
} سلام
متد SetConnectionString که در واقع کانکشن استرینگ را ست میکند و تنها زمانی مفید خواهد بود که کانکشن استرینگها به یک نوع Rdbms متصل شوند . مثلا همه کانکشن استرینگ ها به کانکشنهای مختلفی اشاره کند که همگی به دیتابیسهای مختلف sql server متصل شوند.
اما اگر یک کانکشن استرینگ به sql server و یک کانکشن استرینگ به دیتابیسی از نوع sql ce یا نوعهای دیگه متصل شود با خطای provider مواجه خواهیم شد. چرا که کانکشن استرینگ ، کانکشن ست شده و Provider آن از کانکشن پیش فرض مقدار گرفته است . و عملا هم نمیتوان provider را در این تابع مقدار داد چرا که Readonly است!
public static string CreateConnectionStringForSQLCe(string dbPath = @"|DataDirectory|\NerdDinners.sdf")
{
SqlCeConnectionStringBuilder sqlConnection = new SqlCeConnectionStringBuilder();
sqlConnection.Password = "9023fase93";
sqlConnection.DataSource = dbPath;
EntityConnectionStringBuilder connection = new EntityConnectionStringBuilder();
connection.Metadata = @"res://*/NerdDinnersModel.csdl|res://*/NerdDinnersModel.ssdl|res://*/NerdDinnersModel.msl";
connection.Provider = "System.Data.SqlServerCe.3.5";
connection.ProviderConnectionString = sqlConnection.ToString();
return connection.ToString();
}
public static string CreateConnectionStringForSQLServer()
{
//Build an SQL connection string
SqlConnectionStringBuilder sqlString = new SqlConnectionStringBuilder()
{
DataSource = "MyPC", // Server name
InitialCatalog = "db1", //Database
UserID = "user1", //Username
Password = "mypassword", //Password
};
//Build an Entity Framework connection string
EntityConnectionStringBuilder entityString = new EntityConnectionStringBuilder
{
Provider = "System.Data.SqlClient",
Metadata = "res://*/testModel.csdl|res://*/testModel.ssdl|res://*/testModel.msl",
ProviderConnectionString = sqlString.ToString()
};
return entityString.ConnectionString;
}