实战Angular2+web api增删改查 (一)

Angular2是一个前端开发框架,在引入ts之后使得我们这些C#开发者能够更快的熟悉该框架,angular2开发首先要知道这是一个SPA(单页应用),我们要摆脱以往的asp.net中的MVC模式的固有思路,angular2开发重点是组件(Component),所以开发之前尤其要能清楚这个概念。

在与angular2配合使用的后端(RestFul)我采用的是基于asp.net的web api2.0,这也是目前比较流行的一种方式。我在webapi开发中在数据层使用的是基于NHibernate的Repository+UnitWork模式,自然也会用到依赖注入,我选的依赖注入工具是AutoFac。在前端与后端的数据传递使用DTO,为了方便,使用的是AutoMapper做数据映射。下面从底层开始,以一个简单实例演示整个过程。

领域模型

在建模时曾考虑使用EF6,目前也有很多关于EF6的争议就是EF中实际已包含了Repository和UnitOfWork模式,那么在使用EF时就不必再使用这种模式了,为了能够熟练这种模式我选用了NHibernate作为ORM框架。

数据实体类

public class TGroup : EntityBase {

        public TGroup() {

            Users = new List<TUser>();

        }

        public virtual string ID { getset; }

        public virtual string GROUPNAME { getset; }

        public virtual decimal? NORDER { getset; }

        public virtual string PARENTID { getset; }

        public virtual DateTime? CREATED { getset; }

        public virtual string GROUPTYPE { getset; }

        public virtual string GROUPCODE { getset; }

        public virtual IList<TUser> Users { getset; }

    }

数据实体类都继承于EntityBase,EntityBase是一个空的类,目前没有任何属性及方法,只是为了在使用Repositroy模式时方便,其实可以抽象出诸如ID这样的公共属性出来。

关系映射

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping assembly="URS.Data" namespace="URS.Data.Model" xmlns="urn:nhibernate-mapping-2.2">
  <class name="TGroup" table="T_GROUP" lazy="true" >
    <id name="ID" column="ID" />
    <property name="GROUPNAME">
      <column name="GROUPNAME" sql-type="VARCHAR2" not-null="false" />
    </property>
    <property name="NORDER">
      <column name="NORDER" sql-type="NUMBER" not-null="false" />
    </property>
    <property name="PARENTID">
      <column name="PARENTID" sql-type="VARCHAR2" not-null="false" />
    </property>
    <property name="CREATED">
      <column name="CREATED" sql-type="DATE" not-null="false" />
    </property>
    <property name="GROUPTYPE">
      <column name="GROUPTYPE" sql-type="VARCHAR2" not-null="false" />
    </property>
    <property name="GROUPCODE">
      <column name="GROUPCODE" sql-type="VARCHAR2" not-null="true" />
    </property>
    <bag name="Users" inverse="true" cascade="all">
      <key column="GROUPID" />
      <one-to-many class="TUser" />
    </bag>
  </class>
</hibernate-mapping>

在实体类中就可以看出这是一个一对多关系,TGroup包含了一个TUser集合,所以在映射时使用的bag中描绘了这个一对多关系,这里需要说明的是我所使用的是oracle数据库。

NHibernate配置

<?xml version="1.0" encoding="utf-8"?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <session-factory>
    <property name="connection.driver_class">NHibernate.Driver.OracleManagedDataClientDriver</property>
    <property name="connection.connection_string">User Id=urs;Password=urs;Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=ORA11G)))</property>
    <property name="show_sql">true</property>
    <property name="dialect">NHibernate.Dialect.Oracle10gDialect</property>
    <property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
    <property name="current_session_context_class">call</property>
    <mapping assembly="URS.Data"/>
  </session-factory>
</hibernate-configuration>

这是一个使用oracle的odp的连接配置,这个配置文件需要放在WebAPI解决方案下

Repository模式

IRepository接口

public interface IRepository<TEntity> :IDependency where TEntity : EntityBase
    {
         TEntity Get(object id);
 
         IList<TEntity> GetAll();
         void Add( TEntity entity);
         void Update(TEntity entity);
         void Delete(TEntity entity);
         void Delete(object id);
       
 
        
    }

这里的IRepository接口只提取了部分通用的CURD操作,这里需要注意的是该接口继承了IDependency,这是为了我们下面使用依赖注入的一个空接口,下面会说到这样的目的。

Repository基类

public  class NHRepositoryBase<TEntity> : IRepository<TEntity> where TEntity : EntityBase
    {
        protected virtual ISession Session
        {
            get
            {
                return SessionBuilder.GetCurrentSession();
            }
        }
 
        public virtual TEntity Get(object id)
        {
            return Session.Get<TEntity>(id);
            
        }
 
        public virtual IList<TEntity> GetAll()
        {
            return Session.CreateCriteria<TEntity>()
                .List<TEntity>();
        }
 
        public virtual void Add(TEntity entity)
        {
            try
            {
                Session.Save(entity);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
 
        public virtual void Update(TEntity entity)
        {
            try
            {
                Session.SaveOrUpdate(entity);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
 
        public virtual void Delete(TEntity entity)
        {
            try
            {
                Session.Delete(entity);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
 
        public virtual void Delete(object id)
        {
            try
            {
                TEntity entity=this.Get(id);
                Session.Delete(entity);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }

由于我们使用的是NHibernate,所以我们需要一个全局的ISession,SessionBuilder是我封装的一个类,用来处理ISession,保障一个应用中只有一个ISession实例。

业务Repository

public class GroupRepository : NHRepositoryBase<TGroup>,IGroupRepository
    {
       
    }

由于Repository基类中包含了通用的CURD操作,所以这个GroupRepository 只需继承这个基类即可,如果还有其他操作或属性则再进一步抽象出IGroupRepository这里我还没打算加入其他操作所以IGroupRepository是个空的接口,以后也许会加入其他方法或属性。

UnitOfWork模式

unitofwork模式重点是处理事务,对变化的数据一次提交保证数据完整性。

IUnitOfWork接口

public interface IUnitOfWork : IDisposableIDependency
   {
       IRepository<TEntity> BaseRepository<TEntity>() where TEntity : EntityBase;
       void BeginTransaction();
       void Commit();
       void Rollback();
   }

这个接口同样也继承了IDependency,也是为了后面的依赖注入。在这个接口中我还定义了一个IRepository<TEntity>的属性,这是一个能够根据实体类来获取其对应的Repository。

UnitOfWork实现

public class NHUnitOfWork:IUnitOfWork
   {
       private ITransaction _transaction;
       private Hashtable _repositories;
       public  ISession Session
       {
           get
           {
               return SessionBuilder.GetCurrentSession();
           }
       }
 
       public NHUnitOfWork()
       {
           
       }
       public void BeginTransaction()
       {
           this._transaction = Session.BeginTransaction() ;
       }
 
       public void Commit()
       {
           try
           {
               // commit transaction if there is one active
               if (_transaction != null && _transaction.IsActive)
                   _transaction.Commit();
           }
           catch
           {
               // rollback if there was an exception
               if (_transaction != null && _transaction.IsActive)
                   _transaction.Rollback();
 
               throw;
           }
           //finally
           //{
           //    Session.Dispose();
           //}
       }
 
       public void Rollback()
       {
           //try
           {
               if (_transaction != null && _transaction.IsActive)
                   _transaction.Rollback();
           }
           //finally
           //{
           //    Session.Dispose();
           //}
       }
 
       public void Dispose()
       {
           Session.Dispose();
       }
 
       public IRepository<T> BaseRepository<T>() where T : EntityBase
       {
           if (_repositories == null)
               _repositories = new Hashtable();
 
           var type = typeof(T).Name;
 
           if (!_repositories.ContainsKey(type))
           {
               var repositoryType = typeof(NHRepositoryBase<>);
 
               var repositoryInstance =
                   Activator.CreateInstance(repositoryType
                           .MakeGenericType(typeof(T)));
 
               _repositories.Add(type, repositoryInstance);
           }
 
           return (IRepository<T>)_repositories[type];
       }
   }

这里使用了反射创建Repository实例,这里是创建的通用基类型的Repository实例,好处就是当我们在业务逻辑层使用UnitOfWork时如果是通用的操作,则不用注入Repository了,否则可能要构造中可能要注入很多业务Repository,比较麻烦,当然如果不是通用操作的话,还是要注入的,下面会讲到。

业务逻辑层应用

public class GroupService:IGroupService
    {
        private IUnitOfWork _unitOfWork;
        private IGroupRepository _groupRepository;
        public GroupService(IUnitOfWork unitOfWork,IGroupRepository groupRepository)
        {
            _unitOfWork = unitOfWork;
            _groupRepository = groupRepository;
        }
        public IList<TGroup> GetAll()
        {
            IRepository<TGroup> repo = _unitOfWork.BaseRepository<TGroup>();
            return repo.GetAll();
 
        }
 
        public TGroup GetByID(string id)
        {
            IRepository<TGroup> repo = _unitOfWork.BaseRepository<TGroup>();
            return repo.Get(id);
        }
 
        public void Add(TGroup entity)
        {
            _unitOfWork.BeginTransaction();
            IRepository<TGroup> repo = _unitOfWork.BaseRepository<TGroup>();
            repo.Add(entity);
            _unitOfWork.Commit();
        }
 
        public void Delete(string id)
        {
            _unitOfWork.BeginTransaction();
            IRepository<TGroup> repo = _unitOfWork.BaseRepository<TGroup>();
            repo.Delete(id);
            _unitOfWork.Commit();
        }
 
        public void Update(TGroup entity)
        {
            _unitOfWork.BeginTransaction();
            IRepository<TGroup> repo = _unitOfWork.BaseRepository<TGroup>();
            repo.Update(entity);
            _unitOfWork.Commit();
        }
    }

这里通过在构造函数中注入IUnitOfWork ,IGroupRepository这里可以看到,由于在本例中使用的都是通用的数据CURD,所以实际上IGroupRepository并没有使用,而实际使用的是IUnitOfWork中创建的IRepository<TGroup>,由于这个例子比较简单,如果是由复杂业务逻辑的话,那么需要在_unitOfWork.BeginTransaction()到_unitOfWork.Commit()之间完成业务处理即可保障数据提交的一致性,如果这中间有异常,IUnitOfWork会回滚,这就意味着要么全部提交,要不都不提交。

这里的GroupService继承了IGroupService而IGroupService也会继承IDependency下面将在WebApi的解决方案中介绍AutoFac的依赖注入使用方法。
  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Angular是一种流行的前端框架,可以用于开发Web应用程序。在Angular中,可以使用一些关键的概念和功能来进行增删改查操作。 增加数据:在Angular中,可以使用表单来收集用户输入的数据,并将其绑定到组件中的属性。然后,可以使用这些属性将数据发送到服务器或将其添加到本地存储中。在你提供的引用中,可以看到一个示例的HTML代码,它展示了如何使用Angular的表单控件来收集数据。 删除数据:要删除数据,你可以使用组件中的方法来处理删除操作。这个方法可以从服务器或本地存储中删除数据。在你提供的引用中,没有直接关于删除操作的代码,但你可以在组件中定义一个方法来处理删除操作,并使用适当的逻辑来删除数据。 修改数据:要修改数据,你可以使用表单控件来显示要修改的数据,并将其绑定到组件中的属性。然后,可以使用这些属性来更新服务器上的数据或本地存储中的数据。 查询数据:要查询数据,你可以使用HTTP服务来向服务器发送请求,并获取返回的数据。你可以在组件中定义一个方法来处理查询操作,并使用适当的逻辑来处理返回的数据。 总的来说,Angular提供了丰富的功能和工具来进行增删改查操作。你可以使用表单来收集数据、使用方法来处理增删改操作,并使用HTTP服务来查询数据。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [实战Angular2+web api增删改查(三)](https://blog.csdn.net/huangyezi/article/details/51884747)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值