最近因为项目需要,研究了下EF的读写分离,所以做了一个demo进行测试,下面是项目的结构
表现层view
主要提供Web、WebApi等表现层的解决方案
公共层public
主要提供项目公共类库,数据缓存基础方法等
实体层model
主要提供数据库映射模型,还有就是DDD领域操作模型
数据层Db
主要封装EF操作基础类
数据服务层Service
主要提供数据库操作服务、缓存操作服务
数据接口服务层inface
主要提供数据库操作服务接口、缓存操作服务接口
1.首先是多数据库的支持,目前就支持mysql/sqlservice,如果需要添加更多的数据库支持,只需要再数据库操作类型上面添加即可
///
///数据库类型///
public enum DbContextType : byte{
SqlService= 1,
MySql= 2}
View Code
分别对mysql/sqlservice的上下文操作进行封装
///
///MySql操作类///
[DbConfigurationType(typeof(MySqlEFConfiguration))]public classMySqlContext : DbContext
{public DbSet TestEntities { get; set; }///
///配置默认的字符串链接///
public MySqlContext() : base("DefaultConnection") {
}///
///自定义数据库链接///
///
public MySqlContext(string connenction) : base(connenction) { }///
///实体对应规则的映射配置///
///
protected override voidOnModelCreating(DbModelBuilder modelBuilder)
{
}
}
View Code
///
///Sql数据库操作类///
public classSqlServiceContext : DbContext
{///
///配置默认的字符串链接///
publicSqlServiceContext() {
}///
///自定义数据库链接///
///
public SqlServiceContext(string connenction) : base(connenction) {
}///
///实体对应规则的映射配置///
///
protected override voidOnModelCreating(DbModelBuilder modelBuilder)
{
}
}
View Code
在view调用时候,进行ef上下文初始化只需要设置类型
///
///数据库策略初始化类///
public static classDBInitializer
{public static DbContextType DbContextType { get; set; }///
///数据库初始化策略配置/// `
public static voidInitialize(DbContextType ContextType)
{string IsUsedWR = System.Configuration.ConfigurationManager.AppSettings["IsUsedWR"];
DbContextType=ContextType;///获得数据库最后一个版本
//Database.SetInitializer(new MigrateDatabaseToLatestVersion());
if (ContextType ==DbContextType.SqlService)
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion());if (IsUsedWR == "1") {
Database.SetInitializer(new MigrateDatabaseToLatestVersion());
}else{
Database.SetInitializer(null);
}
}else{
Database.SetInitializer(new MigrateDatabaseToLatestVersion());if (IsUsedWR == "1")
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion());
}else{
Database.SetInitializer(null);
}//Database.SetInitializer(null);//Database.SetInitializer(null);
}//Database.SetInitializer(null);
///删除原来数据库 重新创建数据库
//Database.SetInitializer(new DropCreateDatabaseIfModelChanges());//Database.SetInitializer(new DropCreateDatabaseIfModelChanges());
}
}
View Code
public classMvcApplication : System.Web.HttpApplication
{protected voidApplication_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);//Autofac//ContainerBuilder builder = new ContainerBuilder();//builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly());//IContainer container = builder.Build();//DependencyResolver.SetResolver(new AutofacDependencyResolver(container));//Autofac初始化过程
ContainerBuilder builder = newContainerBuilder();
builder.RegisterControllers(System.Reflection.Assembly.GetExecutingAssembly());//注册mvc容器的实现
var assemblys = BuildManager.GetReferencedAssemblies().Cast().ToList();
builder.RegisterAssemblyTypes(assemblys.ToArray()).Where(t=> t.Name.Contains("Service")).AsImplementedInterfaces();var container =builder.Build();
DependencyResolver.SetResolver(newAutofacDependencyResolver(container));//初始化数据库
DBInitializer.Initialize(DbContextType.MySql);
}
}
View Code
通过上面多数据库的支持已经完成,下面进行读写分离,分别进行继承上述上下文操作
///
///读///
public classWriteSqlServiceContext : SqlServiceContext
{public WriteSqlServiceContext() : base("") { }
}///
///写///
public classReadSqlServiceContext : SqlServiceContext
{public ReadSqlServiceContext() : base("") { }
}
View Code
通过工厂类进行初始化
///
///上下文工厂类///
public static classContextfactory
{///
///获取上下文///
///
public staticDbContext GetContext(DbOpertionType OpertionType)
{
DbContextType ContextType=DBInitializer.DbContextType;if (ContextType ==DbContextType.MySql)
{if (OpertionType ==DbOpertionType.Read)return newReadMySqlContext();else
return newWriteMySqlContext();
}else{if (OpertionType ==DbOpertionType.Read)return newReadSqlServiceContext();else
return newWriteSqlServiceContext();
}
}///
///获取上下文操作///
///
///
///
public static TEntity CallContext(DbOpertionType OpertionType) whereTEntity: DbContext
{var DbContext =GetContext(OpertionType);return(TEntity)DbContext;
}
}
View Code
最后配置webcofig即可
View Code
最后进行测试
public classTestController : Controller
{private ITestService _TestServiceDb { get; set; }publicTestController(ITestService TestServiceDb) {
_TestServiceDb=TestServiceDb;
}//GET: Test
publicActionResult Index()
{var result = _TestServiceDb.AddEntity(new Test() { ID=Guid.NewGuid(), Age=11, CreateTime=DateTime.Now, Name="Test"});var NewResult =_TestServiceDb.GetEntityByID(result.ID);returnView();
}
}
View Code
搞定,可能在代码上有点累赘,但是总算是可行的。
如果有兴趣的朋友可以留下邮箱,然后发全代码一起研究,谢谢!