码迷,mamicode.com
首页 > 编程语言 > 详细

Asp.Net MVC +WCF+EF+Spring 实现云效果!

时间:2015-07-31 18:30:54      阅读:1757      评论:0      收藏:0      [点我收藏+]

标签:wcf   asp.net   mvc      切换数据源   

    这篇博客给大家介绍一下如何通过Asp.Net+WCF+EF实现云效果!

首先给大家介绍一下什么是云效果。

        这次我们做的项目叫做高校云平台,“云”其实是互联网的一个隐喻,“云计算”其实就是使用互联网来接入存储或者运行在远程服务器端的应用,数据,或者服务。在这个项目当中我们秉承着SaaS:Software-as-a-Service(软件即服务)的原则,就是说我们开发一个系统后部署在远程服务器上,其他想用这个系统的人都通过网络来运行就可以了,就是SaaS了。

       高校云平台他首先是为高校服务的一套系统,处理的学校的新生入学,学生信息维护,期末考试,评教…….等工作。但是问题来了,我们既然为每个学校都提供了一套服务,那么我们是不是应该为数据的安全性,数据独立性,考虑一下呢!针对如何存储数据我们想到了三个解决方案。

1.独立数据库

2.共享数据库,隔离数据表

3.共享数据库,共享数据表

        这三个方案各有优缺点,独立数据库,每个学校一个数据库,独立性无疑是很好的,但是他会很占用空间,公测阶段那么多人注册了用户,每个用户都需要有一个库,这样太占用资源了!共享数据库,隔离数据表,这样就是说,所有的学校用一个数据库,但是数据库下有多套数据库表,其实这种方式感觉跟独立数据库差不多。可能就免的建立数据库了!共享数据库,共享数据表,这样所有的用户就用一套数据库,一个数据库表,但是每个学校的数据用一个字段来表示,这样做确实会很省空间,但是数据量一大之后,我们就会效率就会很难被保障了。

         后来经过分析,我们选择了,每个学校用一套数据库,这样数据库的独立性,安全性,都会被保障。下边来看一下,我们是如何实现这种效果的,每个人登陆后,能看到自己的数据!

          先说一下思路,登陆以后--->取到该用户的登陆信息---->通过wcf传递到服务端---->写入线程变量中,在我们实例化数据库上下文的时候,从线程变量中取出!

    下边给出几个关键地方的代码!

    1.定义一个BaseController,该类中有一个保护类型的变量,让其他的controller继承这个controller

<span style="font-size:18px;">namespace LFBidSystem.Controllers
{
     public class BaseController : Controller
     {
	  //每个controller都有的一个变量。用来存放
	  protect string connectionString = "";
     }
}</span>

    2.定义一个拦截器,在每个controller内的action执行之前,都要拦截,并执行controller中的方法!

<span style="font-size:18px;">	namespace LFBidSystem.Controllers
	{
	    public class SwtichDbfilter : ActionFilterAttribute
	    {
	        public override void OnActionExecuting(ActionExecutingContext filterContext)
	        {
	            //获取当前controller 的实力 
	            BaseController cl =(BaseController) filterContext.Controller;
	
	            //给当前调用的controller赋值,本初采用的假数据!
	            cl.connectionString = "Data Source=192.168.24.233;user id=sa;password=123456;persist security info=True;database=SwitchDataSource";
	        }      
	    }
	}
</span>
       3.这样,我们当前调用的controllerconnectionString变量就会有值了!这样我们就可以在调用wcf的时候,将这个参数传递到服务端,

<span style="font-size:18px;">	namespace LFBidSystem.Controllers
	{
	    public class testController : BaseController
	    {
	        IUserInfoWCF iUserInfoWcf = ServiceFactory.GetUserInfosService();
	        public ActionResult Index()
	        {
	            string userInfo = Request["userInfo"];
	            ViewData["userInfo"] = userInfo;
	            return View();
	        }
	
	        public string Login() { 
	
	             UserInfoViewModel enUser = new UserInfoViewModel();
	            //获取用户名
	            string strUserName = Request["userName"];
	            //获取密码
	            string strPassWord = Request["passWord"];
	
	            //调用wcf 的方法  进行登录
	            UserInfoViewModel enUserInfoVM = new UserInfoViewModel();
	            enUserInfoVM.UserName = strUserName;
	            enUserInfoVM.PassWord = strPassWord;
	            //取得链接字符串的值,这个值在filter 中已经赋值了!
	            enUserInfoVM.DataSource = this.connectionString;
	
	            try
	            {
			传递的变量中,包括connectionString 的值!
	                enUser = iUserInfoWcf.Login(enUserInfoVM);
	            }
	            catch (Exception e)
	            { }
	            return enUser.other;
	        }
	
	    }
	}
</span>


       4.我们拿到传递过来的connectionString,并将这个值写入到线程变量中!

<span style="font-size:18px;">namespace LFBidSystem.WCFService
{
      public partial class ServiceBusiness : IUserInfoWCF
	    {
	        //拿到业务逻辑层的接口
	       // IUserManagerBll iUserManagerBll = SpringHelper.GetObject<IUserManagerBll>("UserManager");
	        IUserManagerBll iUserManagerBll = null;
	        #region   Login   登录   张宏杰 2015年6月6日16:37:19
	        /// <summary>
	        /// 登录  
	        /// </summary>
	        /// <param name="enUserInfoVM">用户信息实体</param>
	        /// <returns>提示条信息</returns>
	        public UserInfoViewModel Login(UserInfoViewModel enUserInfoVM)
	        {
	            //设置连接字符串到线程变量中 
	            CallContext.SetData("databaseId", enUserInfoVM.DataSource);
	            iUserManagerBll = SpringHelper.GetObject<IUserManagerBll>("UserManager");
	            return iUserManagerBll.Login(enUserInfoVM);
	        }
	        #endregion
	    }
}
</span>
        5.在我们实例化数据库上下文的时时候,我们要拿到这个链接字符串来进行实例化!这样我们实例化的上下文对象就是对链接字符串对应的那个库进行操作了!

<span style="font-size:18px;">namespace LFBidSystem.DAL
{
    public class BaseDal<T> : CoreBaseDal<T> where T : class,new()
    {
        public SchoolWoeDbContext switchDataSourceEntity;

        public override void SetDbContext()
        {
            //从缓存中取出上下文的链接信息
          string databaseId =  CallContext.GetData("databaseId").ToString();

          DbContext db = CallContext.GetData("DbContextFactory") as SchoolWoeDbContext;

            if (db == null)
            {
                //根据数据库上下文的链接信息,实例化数据库上下文。该上下文会采用才链接字符串进行创建!
                db = new SchoolWoeDbContext(databaseId);
                //从缓存中拿到这个信息
              //  db = SpringHelper.GetObject<DbContext>("SwitchDataSourceEntities");
                //TODO:DbContext,线程内缓存,不适用于集群,后期分布式缓存进行处理,key为guid
                CallContext.SetData("DbContextFactory", db);
            }
            this.MyBaseDbContext = db;
            switchDataSourceEntity = (SchoolWoeDbContext)db;
        }

    }
}
</span>
        6.们的ORM框架采用的是EF,都知道他有三种模式,具体那种模式的好处,有缺点,我们可以查一些资料,本架构采用的是codeFirst数据源上下文类。

<span style="font-size:18px;">namespace ModelText
{
    public class SchoolWoeDbContext : DbContext
    {
        public SchoolWoeDbContext(string ConncectionString)
            : base(ConncectionString)
        {
            this.Database.CreateIfNotExists();
        }

        public virtual DbSet<T_User> T_User { get; set; }

        public virtual DbSet<T_DataSource> T_DataSource { get; set; }
    }
}
</span>

       通过这些操作,我们的动态切换数据源就可以很好的实现了!


版权声明:本文为博主原创文章,未经博主允许不得转载。

Asp.Net MVC +WCF+EF+Spring 实现云效果!

标签:wcf   asp.net   mvc      切换数据源   

原文地址:http://blog.csdn.net/zhanghongjie0302/article/details/47135463

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!