zoukankan      html  css  js  c++  java
  • 中大型系统架构组合之EF4.1+ASP.NET MVC+JQuery

    EF4.1已经推出有一段时间了,它给人的第一吸引力就是比LINQ TO SQL更加适合大型项目,它的封装更加紧密,操作也更加灵活,而且弥补了LINQ To SQL的最大不足,可以支持多种数据库。

    image

    EF4.1+ASP.NET MVC+JQuery

    第一先说一下EF4.1:

    我们数据层OR/Mapping采用EF4.1来实现数据的持久化

    image

    我们必须要对EF4.1进行一个封装,把对数据的操作限制在DATA层,不能向上一层暴露太多实现的细节,这样作是安全的,层次分明的。

    对数据操作有一个泛型接口来实现:

    namespace Data
    {
        /// <summary>
        /// 数据操作统一接口(插入,查詢,刪除,更新)
        /// </summary>
        public interface IEntityRepository<TEntity> where TEntity : class //这里使用泛型接口
        {
     
            /// <summary>
            /// 插入单条记录
            /// </summary>
            void Insert(TEntity entity);
     
            /// <summary>
            /// 插入列表
            /// </summary>
            void Insert(IList<TEntity> list);
     
            /// <summary>
            /// 删除单条记录
            /// </summary>
            /// <param name="entity"></param>
            void Delete(TEntity entity);
     
            /// <summary>
            /// 删除列表
            /// </summary>
            /// <param name="list"></param>
            void Delete(IList<TEntity> list);
     
            /// <summary>
            /// 更新单条记录
            /// </summary>
            /// <param name="entity"></param>
            void Update(TEntity entity);
     
            /// <summary>
            /// 更新列表
            /// </summary>
            /// <param name="list"></param>
            void Update(IList<TEntity> list);
     
            /// <summary>
            /// 得到实体列表
            /// </summary>
            /// <returns></returns>
            IDbSet<TEntity> GetList();
     
            TEntity GetEntityById(TEntity entity);
        }
     
    }

    通过EntityRepository<TEntity> 这个泛型类去实现上面接口,为表示层只公开操作及签名

    namespace Data
    {
        /// <summary>
        /// 数据操作实现类(统一实现类)
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        public class EntityRepository<TEntity> : RepositoryBase, IEntityRepository<TEntity>
            where TEntity : class,Entity.IEntity
        {
            #region IEntityRepository<TEntity> Members
     
            public void Insert(TEntity entity)
            {
                this.Db.Set<TEntity>().Add(entity);
                this.Db.Entry(entity).State = System.Data.EntityState.Added;
                this.SaveChanges();
            }
     
            public void Insert(IList<TEntity> list)
            {
                list.ToList().ForEach(entity =>
                {
                    this.Db.Set<TEntity>().Add(entity);
                    this.Db.Entry(entity).State = System.Data.EntityState.Added;
                });
                this.SaveChanges();
            }
     
            public void Delete(TEntity entity)
            {
                this.Db.Set<TEntity>().Remove(entity);
                this.Db.Entry(entity).State = System.Data.EntityState.Deleted;
                this.SaveChanges();
            }
     
            public void Delete(IList<TEntity> list)
            {
                list.ToList().ForEach(entity =>
                {
                    this.Db.Set<TEntity>().Remove(entity);
                    this.Db.Entry(entity).State = System.Data.EntityState.Deleted;
                });
                this.SaveChanges();
            }
     
            public System.Data.Entity.IDbSet<TEntity> GetList()
            {
                return this.Db.Set<TEntity>();
            }
     
            public TEntity GetEntityById(TEntity entity)
            {
     
                return this.Db.Set<TEntity>().Find(entity.Id);
            }
     
            public void Update(TEntity entity)
            {
                var entry = this.Db.Entry(entity);//从DbContext类型的对象
                if (entry.State == EntityState.Detached)
                {
                    var entityToUpdate = this.Db.Set<TEntity>().Find(entity.Id);

    EmitMapper.ObjectMapperManager.DefaultInstance.GetMapper<TEntity,

    TEntity>().Map(entity, entityToUpdate);

                    this.SaveChanges();
                }
            }
     
            public void Update(IList<TEntity> list)
            {
                list.ToList().ForEach(entity =>
                {
                    var entry = this.Db.Entry(entity);
                    if (entry.State == EntityState.Detached)
                    {
                        var entityToUpdate = this.Db.Set<TEntity>().Find(entity.Id);
                        EmitMapper.ObjectMapperManager.DefaultInstance.GetMapper<TEntity, 
                        TEntity>().Map(entity, entityToUpdate);
                        this.SaveChanges();
                    }
                });
            }
     
            #endregion
     
            /// <summary>
            /// 操作提交
            /// </summary>
            public override void SaveChanges()
            {
                base.SaveChanges();
            }
        }
     
    }

    当然,对于一个特殊的操作逻辑,我们要进行特殊的处理,如可以单独建立用户操作接口,产品操作接口等,而对于逻辑简单的模块,使用上面通过方法足以。

    Entity实体层,我没有进行刻意的再封装,因为EF4.1帮助我们生成的代码已经基本满足了要求,它不向LINQ TO SQL 把操作与类实体混在一起,它是分开的。对于通用的更新操作,我们还需要人为干预一下Entity的实体类,如下:

    image

    IEntity通用接口会提供一个属于让继承它的实体类去实现,这个属性就是表主键,用来唯一确定一个实体。

    namespace Entity
    {
        /// <summary>
        /// 实体模块统一接口
        /// </summary>
        public interface IEntity
        {
            /// <summary>
            /// 为了主键统一,而手动设置的
            /// TODO:这是为了泛型的统一操作而设计的,非常经典 
            /// </summary>
            string Id { get; }
        }
    }
    而Menu这个实体会这样描述它:
     
    namespace Entity.Entities
    {
        public class Menu:Entity.IEntity
        {
            public Menu()
            {
                this.Role_Menus = new List<Role_Menus>();
            }
     
            public int MenuID { get; set; }
            public string URL { get; set; }
            public int ParentID { get; set; }
            public string MenuName { get; set; }
            public System.DateTime CreateDate { get; set; }
            public System.DateTime UpdateDate { get; set; }
            public int Status { get; set; }
            public int SortNum { get; set; }
            public string Operator { get; set; }
            public int Type { get; set; }
            public virtual ICollection<Role_Menus> Role_Menus { get; set; }
     
            #region IEntity 成员
     
            public string Id
            {
                get { return this.MenuID.ToString(); }
            }
     
            #endregion
        }
    }

    实事上,Entity层是一个共享层,它可以同时被Data,Service和WebUI层访问,Service层用来与Data层直接进行交互。

    image

    它定义了User模块的逻辑实现接口,它的实现逻辑可以由多个类进行实现,这里面我们可以使用IOC以降低类的耦合度。如何实现IOC(控制反转)可以看我的这篇文章

    由于篇幅较大,所以只给出接口代码:

    namespace Service
    {
        public interface IUserService
        {
            List<Entity.Entities.UserBas> GetUserBases();
            Entity.Entities.UserBas GetUserBaseById(string id);
            void AddUserBase(Entity.Entities.UserBas entity);
            void ModifyUserBase(Entity.Entities.UserBas entity);
            void DeleteUserBase(Entity.Entities.UserBas entity);
            void DeleteUserBase(List<Entity.Entities.UserBas> entity);
        }
    }

    WebUI层将会涉及到我们讲的ASP.NET MVC 和 JQuery

    实事上,MVC是WebUI层的一种架构方式,它可以表代码与页面逻辑分离开,表码层控制与它下一层的信息交互,而页面表现层只负责输出HTML代码及JS效果。

    image

    我们看到图中还有一个Models,它就可以MVC中的M,它叫做视图模型,我理解为,它是与页面相关的,为页面提供数据的类实体,比如,为用户中心(包括登陆,注册,修改密码等等)提供显示及验证逻辑等功能的都写在LogOnModels这个类里,这样在修改显示信息时,直接去这个类里修改就可以了。

    JQuery它是JS的一种功能强大的类库,当你建立一个MVC项目时,它会被自动添加进来,(看来微软也开源了,:P),它可以实现页面的扩展效果,如动态的列表,菜单,验证机制等等。

    image

    我们可以看到VS2010自代的版本是1.4.1,是目前较新版本,而-vsdoc.js是一个jquery代码智能提供的工具,有了jquery我们在写js脚本时就方便多了,看这是一个ajax请求的例子:

       function list(id) {
            $("#cateid").val(id);
            clickHoverColor();
            $.ajax({
                type: "POST",
                url: "/down/List",
                data: { cateid: id },
                success: function(data) {
                    $("#list").html(data);
                }
            });

    是不是很清晰,很方便呢!如果想了解更多的js知识,可以看这篇文章

    今天就写到这吧!

  • 相关阅读:
    deepin15.11安装Oracle JDK
    API文档-BASE-BASE
    miniui控件的el属性(自动生成的标签)
    miniui从继承看控件处理
    miniui中的继承
    miniui加载(二)
    miniui 加载文件时会做的一些事情
    二、运行盛派的Demo(看下效果)
    一、选择云服务器和测试微信公众号Token
    绘制圆角(2)
  • 原文地址:https://www.cnblogs.com/lori/p/2172392.html
Copyright © 2011-2022 走看看