http://www.php361.com/index.php?c=index&a=view&id=3857
不建议用,太重的框架EF,仅仅参考一下别人的思路就好。
[导读]最近因为项目需要,研究了下EF的读写分离,所以做了一个demo进行测试,下面是项目的结构表现层view 主要提供Web、WebApi等表现层的解决方案公共层public 主要提供项目公共类库,数据缓存基础方法等实体层model 主要提供数据
最近因为项目需要,研究了下EF的读写分离,所以做了一个demo进行测试,下面是项目的结构
表现层view
主要提供Web、WebApi等表现层的解决方案
公共层public
主要提供项目公共类库,数据缓存基础方法等
实体层model
主要提供数据库映射模型,还有就是DDD领域操作模型
数据层Db
主要封装EF操作基础类
数据服务层Service
主要提供数据库操作服务、缓存操作服务
数据接口服务层inface
主要提供数据库操作服务接口、缓存操作服务接口
1.首先是多数据库的支持,目前就支持mysql/sqlservice,如果需要添加更多的数据库支持,只需要再数据库操作类型上面添加即可
[源码] view plain
/// <summary>
/// 数据库类型
/// </summary>
public enum DbContextType : byte
{
SqlService = 1,
MySql = 2
}
View Code
分别对mysql/sqlservice的上下文操作进行封装
[源码] view plain
/// <summary>
/// MySql操作类
/// </summary>
[DbConfigurationType(typeof(MySqlEFConfiguration))]
public class MySqlContext : DbContext
{
public DbSet<Test> TestEntities { get; set; }
/// <summary>
/// 配置默认的字符串链接
/// </summary>
public MySqlContext() : base("DefaultConnection") {
}
/// <summary>
/// 自定义数据库链接
/// </summary>
/// <param name="connenction"></param>
public MySqlContext(string connenction) : base(connenction) { }
/// <summary>
/// 实体对应规则的映射配置
/// </summary>
/// <param name="modelBuilder"></param>
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
}
View Code
[源码] view plain
/// <summary>
/// Sql数据库操作类
/// </summary>
public class SqlServiceContext : DbContext
{
/// <summary>
/// 配置默认的字符串链接
/// </summary>
public SqlServiceContext() {
}
/// <summary>
/// 自定义数据库链接
/// </summary>
/// <param name="connenction"></param>
public SqlServiceContext(string connenction) : base(connenction) {
}
/// <summary>
/// 实体对应规则的映射配置
/// </summary>
/// <param name="modelBuilder"></param>
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
}
View Code
在view调用时候,进行ef上下文初始化只需要设置类型
[源码] view plain
/// <summary>
/// 数据库策略初始化类
/// </summary>
public static class DBInitializer
{
public static DbContextType DbContextType { get; set; }
/// <summary>
/// 数据库初始化策略配置
/// </summary>`
public static void Initialize(DbContextType ContextType)
{
string IsUsedWR = System.Configuration.ConfigurationManager.AppSettings["IsUsedWR"];
DbContextType = ContextType;
///获得数据库最后一个版本
// Database.SetInitializer<DBContextHelper>(new MigrateDatabaseToLatestVersion<DBContextHelper, DBConfiguration>());
if (ContextType == DbContextType.SqlService)
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<WriteSqlServiceContext, WriteSqlServiceDBConfiguration>());
if (IsUsedWR == "1") {
Database.SetInitializer(new MigrateDatabaseToLatestVersion<ReadSqlServiceContext, ReadSqlSqlServiceDBConfiguration>());
}
else
{
Database.SetInitializer<ReadSqlServiceContext>(null);
}
}
else
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<WriteMySqlContext, WriteMySqlDBConfiguration>());
if (IsUsedWR == "1")
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<ReadMySqlContext, ReadMySqlDBConfiguration>());
}
else
{
Database.SetInitializer<ReadMySqlContext>(null);
}
//Database.SetInitializer<WriteMySqlContext>(null);
// Database.SetInitializer<ReadMySqlContext>(null);
}
// Database.SetInitializer<DBContextHelper>(null);
///删除原来数据库 重新创建数据库
//Database.SetInitializer(new DropCreateDatabaseIfModelChanges<ContextHelper>());
// Database.SetInitializer<ContextHelper>(new DropCreateDatabaseIfModelChanges<ContextHelper>());
}
}
View Code
[源码] view plain
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_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 = new ContainerBuilder();
builder.RegisterControllers(System.Reflection.Assembly.GetExecutingAssembly());//注册mvc容器的实现
var assemblys = BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToList();
builder.RegisterAssemblyTypes(assemblys.ToArray()).Where(t => t.Name.Contains("Service")).AsImplementedInterfaces();
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
//初始化数据库
DBInitializer.Initialize(DbContextType.MySql);
}
}
View Code
通过上面多数据库的支持已经完成,下面进行读写分离,分别进行继承上述上下文操作
[源码] view plain
/// <summary>
/// 读
/// </summary>
public class WriteSqlServiceContext : SqlServiceContext
{
public WriteSqlServiceContext() : base("") { }
}
/// <summary>
/// 写
/// </summary>
public class ReadSqlServiceContext : SqlServiceContext
{
public ReadSqlServiceContext() : base("") { }
}
View Code
通过工厂类进行初始化
[源码] view plain
/// <summary>
/// 上下文工厂类
/// </summary>
public static class Contextfactory
{
/// <summary>
/// 获取上下文
/// </summary>
/// <returns></returns>
public static DbContext GetContext(DbOpertionType OpertionType)
{
DbContextType ContextType = DBInitializer.DbContextType;
if (ContextType == DbContextType.MySql)
{
if (OpertionType == DbOpertionType.Read)
return new ReadMySqlContext();
else
return new WriteMySqlContext();
}
else
{
if (OpertionType == DbOpertionType.Read)
return new ReadSqlServiceContext();
else
return new WriteSqlServiceContext();
}
}
/// <summary>
/// 获取上下文操作
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="OpertionType"></param>
/// <returns></returns>
public static TEntity CallContext<TEntity>(DbOpertionType OpertionType) where TEntity: DbContext
{
var DbContext = GetContext(OpertionType);
return (TEntity)DbContext;
}
}
View Code
最后配置webcofig即可
[源码] view plain
<!--数据库配置(WriteMySqlConnection:读数据库,ReadMySqlConnection:写数据库 如果无需要进行 就配置IsUsedWR,2个链接都写写入库)-->
<connectionStrings>
<add name="WriteMySqlConnection" connectionString="data source=*; Initial Catalog=YK_Test_WriteDB ; uid=root; pwd=yk12345;Charset=utf8" providerName="MySql.Data.MySqlClient" />
<add name="ReadMySqlConnection" connectionString="data source=*; Initial Catalog=YK_Test_ReadDB ; uid=root; pwd=yk12345;Charset=utf8" providerName="MySql.Data.MySqlClient" />
</connectionStrings>
<!--数据库读取分离配置-->
<!--是否开启读写分离 1:开启 0:不开启-->
<add key="IsUsedWR" value="1"/>
View Code
最后进行测试
[源码] view plain
public class TestController : Controller
{
private ITestService _TestServiceDb { get; set; }
public TestController(ITestService TestServiceDb) {
_TestServiceDb = TestServiceDb;
}
// GET: Test
public ActionResult Index()
{
var result = _TestServiceDb.AddEntity(new Test() { ID=Guid.NewGuid(), Age=11, CreateTime=DateTime.Now, Name="Test" });
var NewResult = _TestServiceDb.GetEntityByID(result.ID);
return View();
}
}
View Code
搞定,可能在代码上有点累赘,但是总算是可行的。
|
请发表评论