码迷,mamicode.com
首页 > Web开发 > 详细

MVC实战起步(一):一个简易框架的搭建

时间:2015-11-11 13:19:13      阅读:412      评论:0      收藏:0      [点我收藏+]

标签:

一:引言

这仅仅是一个新手写给新手共同入门的博文!这是一个使用MVC,和一些主流框架(Autofac,Log4Net等)来完成的一个简单的项目。和各位学习MVC的朋友们一起学习。

二:项目分层

技术分享

如左图所示,先建好文件夹,然后再来填充内容。

一:Zero,MVC4.0项目

二:Domain: Abstract仓储类接口,Concrete仓储类实现,Entities实体模型

三:Infrastructure:基础设施

四:IOC:主要用于解耦仓储类接口

 

 

 

 

三:Infrastructure层建设

首先,从最底层写起:

第一步,写一个操作数据库的类

我这边采用的是底层使用ADO.NET,通过泛型约束和反射来实现一个简单的ORM

1:先在Conntion里面放一个SQLHelper类(找个自己熟悉的),这里就不做工厂了。怎么简单怎么来,先让东西跑起来

2:写个属于自己的ORM类:我们先来想想,如果不考虑存储过程(返回集合,直接LINQ处理数据),我们需要什么东西来拼接SQL语句,首先,要有表名,然后主键,然后各个字段名称,其他的先不考虑,现在写一个IDateBase抽象类来约束实体类,往Infrastructure层的IBase文件夹里新建一个IDateBase抽象类,代码如下:

技术分享
namespace Zero.Infrastructure.IBase
{
    public abstract class IDataBase
    {
        public virtual string TableName { get; set; }

        public virtual int ID { get; set; }

    }
}
abstract class IDataBase

这样就解决了表名和主键名称在用泛型的时候,取不到的问题了,但是字段名称不行啊,每个表的字段都不一样,所以最后还是要用到反射,写一个特性来反射,在Infrastructure层的Attributes文件夹下面建立一个类DataFieldAttribute

代码如下:

namespace Zero.Infrastructure.Attributes
{
    public class DataFieldAttribute : Attribute
    {
        private string _FieldName;
        public DataFieldAttribute(string fieldname)
        {
            this._FieldName = fieldname;
        }
        public string FieldName
        {
            get { return this._FieldName; }
            set { this._FieldName = value; }
        }
    }
}

 

完事具备,我们先写一个实体类,然后开始写ORM

实体里建立在Domain的Entities文件夹下面,记得Domain层要引用Infrastructure层

技术分享
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Zero.Infrastructure.Attributes;
using Zero.Infrastructure.IBase;

namespace Zero.Domain.Entities
{
    public class User: IDataBase
    {

        public User()
        {
            TableName = "User";
        }

        private string _TableName;

        public override string TableName
        {
            get
            {
                if (_TableName == null)
                { return "User"; }
                else { return _TableName; }
            }
            set { _TableName = value; }
        }

        public override int ID { get; set; }

        [DataFieldAttribute("UserName")]
        public string UserName { get; set; }

    }
}
View Code

 

代码如上

现在开始写自己的ORM类

在Infrastructure层的Conntion文件夹下面建立一个ZeroORM类,ORM需要实现的功能有:查询,添加,更改,删除,4个基本功能

public class ZeroORMwhere<T> where T : IBase.IDataBase
{

    public string SqlConnctionString { get; set; }
    public SqlConnection conn { get; set; }
    public SqlTransaction tran { get; set; }

}

 

然后增加查询方法:

/// <summary>
    /// 获得实体T所有数据
    /// </summary>
    /// <returns></returns>
    public List<T> Select(T t)
    {
        List<T> list = new List<T>();
        string sql = "select * from " + t.TableName + " WITH (NOLOCK) order by id desc";

        DataSet ds = SqlHelper.ExecuteDataset(SqlConnctionString, CommandType.Text, sql);
        for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
        {
            list.Add(DataSetToEntity.DsToEntity<T>(ds, i));
        }
        return list;
    }

 

DataSetToEntity这个类就是网上找的Dataset转实体的方法,大家可以网上找下,最后返回一个List集合

然后是添加方法

技术分享
/// <summary>
       /// 插入新数据
       /// </summary>
       /// <param name="t">实体类</param>
       /// <returns></returns>
       public int Insert(T t)
       {
           try
           {
               Type mytype = t.GetType();
               // 获取类的所有公共属性
               System.Reflection.PropertyInfo[] pInfo = mytype.GetProperties();
               string FieldName = "";//字段名称
               string Values = "";//
               StringBuilder sql = new StringBuilder();
               List<SqlParameter> paras = new List<SqlParameter>();//不定参集合,防注入

               sql.Append("Insert into ");
               sql.Append(mytype.Name);//数据库表名,可以放t.TableName
               sql.Append("(");
               object[] objDataFieldAttribute = null;
               foreach (System.Reflection.PropertyInfo pio in pInfo)
               {
                   objDataFieldAttribute = pio.GetCustomAttributes(typeof(DataFieldAttribute), false);
                   if (objDataFieldAttribute != null && objDataFieldAttribute.Length > 0)
                   {
                       FieldName += ((DataFieldAttribute)objDataFieldAttribute[0]).FieldName + ",";//给字段赋值
                       Values += "@" + ((DataFieldAttribute)objDataFieldAttribute[0]).FieldName + ",";//给对应字段的值赋值
                       paras.Add(new SqlParameter("@" + ((DataFieldAttribute)objDataFieldAttribute[0]).FieldName, pio.GetValue(t, null)));//添加不定参
                   }
               }
               FieldName = FieldName.TrimEnd(,);
               Values = Values.TrimEnd(,);
               sql.Append(FieldName);
               sql.Append(") VAlUES (");
               sql.Append(Values);
               sql.Append(")");
               int i = SqlHelper.ExecuteNonQuery(SqlConnctionString, CommandType.Text, sql.ToString(), paras.ToArray());
               return i;
           }
           catch (Exception)
           {
               return -1;
               throw;
           }


       }
View Code

 

还有修改和删除方法,以及带事务的方法,一起贴出来。

技术分享
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Reflection;
using System.Text;
using Zero.Infrastructure.Attributes;
using Zero.Infrastructure.Utilities;

namespace Zero.Infrastructure.Conntion
{
    public class ZeroORM<T> where T : IBase.IDataBase
    {


        public string SqlConnctionString { get; set; }
        public SqlConnection conn { get; set; }
        public SqlTransaction tran { get; set; }


        /// <summary>
        /// 获得实体T所有数据
        /// </summary>
        /// <returns></returns>
        public List<T> Select(T t)
        {
            List<T> list = new List<T>();
            string sql = "select * from [" + t.TableName + "] WITH (NOLOCK) order by id desc";  //出于性能考虑,不用反射来获取表名
            DataSet ds = SqlHelper.ExecuteDataset(SqlConnctionString, CommandType.Text, sql);
            for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
            {
                list.Add(DataSetToEntity.DsToEntity<T>(ds, i));
            }
            return list;
        }

        /// <summary>
        /// 根据主键ID获取数据(一条)
        /// </summary>
        /// <param name="id"></param>
        /// <param name="TableName"></param>
        /// <returns></returns>
        public T SelectByID(int id, T t)
        {

            string sql = "select * from [" + t.TableName + "] WITH (NOLOCK) where ID=@ID"; //出于性能考虑,不用反射来获取表名
            DataSet ds = SqlHelper.ExecuteDataset(SqlConnctionString, CommandType.Text, sql, new SqlParameter("@ID", id));
            t = DataSetToEntity.DsToEntity<T>(ds, 0);
            PropertyInfo[] prop = t.GetType().GetProperties();
            return t;


        }

 


        /// <summary>
        /// 插入新数据
        /// </summary>
        /// <param name="t">实体类</param>
        /// <returns></returns>
        public int Insert(T t)
        {
            try
            {
                Type mytype = t.GetType();
                // 获取类的所有公共属性
                System.Reflection.PropertyInfo[] pInfo = mytype.GetProperties();
                string FieldName = "";//字段名称
                string Values = "";//
                StringBuilder sql = new StringBuilder();
                List<SqlParameter> paras = new List<SqlParameter>();

                sql.Append("Insert into [");
                sql.Append(mytype.Name);//数据库表名
                sql.Append("](");
                object[] objDataFieldAttribute = null;
                foreach (System.Reflection.PropertyInfo pio in pInfo)
                {
                    objDataFieldAttribute = pio.GetCustomAttributes(typeof(DataFieldAttribute), false);
                    if (objDataFieldAttribute != null && objDataFieldAttribute.Length > 0)
                    {
                        FieldName += ((DataFieldAttribute)objDataFieldAttribute[0]).FieldName + ",";
                        Values += "@" + ((DataFieldAttribute)objDataFieldAttribute[0]).FieldName + ",";
                        paras.Add(new SqlParameter("@" + ((DataFieldAttribute)objDataFieldAttribute[0]).FieldName, pio.GetValue(t, null)));
                    }
                }
                FieldName = FieldName.TrimEnd(,);
                Values = Values.TrimEnd(,);
                sql.Append(FieldName);
                sql.Append(") VAlUES (");
                sql.Append(Values);
                sql.Append(")");
                int i = SqlHelper.ExecuteNonQuery(SqlConnctionString, CommandType.Text, sql.ToString(), paras.ToArray());
                return i;
            }
            catch (Exception)
            {
                return -1;
                throw;
            }


        }

        /// <summary>
        /// 更新数据
        /// </summary>
        /// <param name="t">需更新的实体类</param>
        /// <returns></returns>
        public int Update(T t)
        {
            try
            {
                int i = 0;
                int primarykey = t.ID;
                T oldT = t;
                Type mytype = t.GetType();
                System.Reflection.PropertyInfo[] pInfo = mytype.GetProperties();
                oldT = SelectByID(primarykey, oldT);//获得原始值,为日志做准备
                if (t != oldT)
                {
                    string SetValue = "";//字段名称
                    string Where = " where ID=@ID";//
                    StringBuilder sql = new StringBuilder();
                    List<SqlParameter> paras = new List<SqlParameter>();
                    sql.Append("Update [");
                    sql.Append(mytype.Name);
                    sql.Append("] Set ");
                    object[] objDataFieldAttribute = null;
                    foreach (System.Reflection.PropertyInfo pio in pInfo)
                    {
                        objDataFieldAttribute = pio.GetCustomAttributes(typeof(DataFieldAttribute), false);
                        if (objDataFieldAttribute != null && objDataFieldAttribute.Length > 0 && pio.GetValue(t, null).ToString() != pio.GetValue(oldT, null).ToString())
                        {
                            SetValue += ((DataFieldAttribute)objDataFieldAttribute[0]).FieldName + "=" + "@" + ((DataFieldAttribute)objDataFieldAttribute[0]).FieldName + ",";
                            paras.Add(new SqlParameter("@" + ((DataFieldAttribute)objDataFieldAttribute[0]).FieldName, pio.GetValue(t, null)));
                        }
                    }

                    SetValue = SetValue.TrimEnd(,);
                    sql.Append(SetValue);
                    sql.Append(Where);
                    paras.Add(new SqlParameter("@ID", primarykey));
                    i = SqlHelper.ExecuteNonQuery(SqlConnctionString, CommandType.Text, sql.ToString(), paras.ToArray());
                    return i;
                }
                else
                {
                    return -2;
                }


            }
            catch (Exception)
            {
                return -1;
                throw;
            }

        }

        /// <summary>
        /// 删除数据
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public int Delete(T t)
        {
            int i = 0;
            int primarykey = t.ID;
            Type mytype = t.GetType();
            string TableName = mytype.Name;
            string Where = " where ID =@ID";
            string sql = "DELETE FROM " + TableName + Where;
            try
            {
                i = SqlHelper.ExecuteNonQuery(SqlConnctionString, CommandType.Text, sql, new SqlParameter("@ID", primarykey));
                return i;
            }
            catch (Exception)
            {
                return -1;
                throw;
            }

        }

        /// <summary>
        /// 开始事务
        /// </summary>
        /// <returns></returns>
        public void BeginTran()
        {
            try
            {
                conn = new SqlConnection(SqlConnctionString);
                conn.Open();
                tran = conn.BeginTransaction();

            }
            catch (Exception)
            {
                tran.Rollback();
                conn.Close();

                throw;
            }

        }

        /// <summary>
        /// 带事务的插入方法
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public int InsertByTran(T t)
        {

            try
            {
                Type mytype = t.GetType();
                // 获取类的所有公共属性
                System.Reflection.PropertyInfo[] pInfo = mytype.GetProperties();
                string FieldName = "";//字段名称
                string Values = "";//
                StringBuilder sql = new StringBuilder();
                List<SqlParameter> paras = new List<SqlParameter>();
                sql.Append("Insert into [");
                sql.Append(mytype.Name);//数据库表名
                sql.Append("](");
                object[] objDataFieldAttribute = null;
                foreach (System.Reflection.PropertyInfo pio in pInfo)
                {
                    objDataFieldAttribute = pio.GetCustomAttributes(typeof(DataFieldAttribute), false);
                    if (objDataFieldAttribute != null && objDataFieldAttribute.Length > 0)
                    {
                        FieldName += ((DataFieldAttribute)objDataFieldAttribute[0]).FieldName + ",";
                        Values += "@" + ((DataFieldAttribute)objDataFieldAttribute[0]).FieldName + ",";
                        paras.Add(new SqlParameter("@" + ((DataFieldAttribute)objDataFieldAttribute[0]).FieldName, pio.GetValue(t, null)));
                    }
                }
                FieldName = FieldName.TrimEnd(,);
                Values = Values.TrimEnd(,);
                sql.Append(FieldName);
                sql.Append(") VAlUES (");
                sql.Append(Values);
                sql.Append(")");
                int i = SqlHelper.ExecuteNonQuery(tran, CommandType.Text, sql.ToString(), paras.ToArray());
                return i;
            }
            catch (Exception)
            {
                tran.Rollback();
                return -1;
                throw;
            }


        }

        /// <summary>
        /// 带事务的更新方法
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public int UpdateByTran(T t)
        {
            try
            {
                int i = 0;
                int primarykey = t.ID;
                T oldT = t;
                Type mytype = t.GetType();
                System.Reflection.PropertyInfo[] pInfo = mytype.GetProperties();
                oldT = SelectByID(primarykey, oldT);//获得原始值,为日志做准备
                if (t != oldT)
                {
                    string SetValue = "";//字段名称
                    string Where = " where ID=@ID";//
                    StringBuilder sql = new StringBuilder();
                    List<SqlParameter> paras = new List<SqlParameter>();
                    sql.Append("Update [");
                    sql.Append(mytype.Name);
                    sql.Append("] Set ");
                    object[] objDataFieldAttribute = null;
                    foreach (System.Reflection.PropertyInfo pio in pInfo)
                    {
                        objDataFieldAttribute = pio.GetCustomAttributes(typeof(DataFieldAttribute), false);
                        if (objDataFieldAttribute != null && objDataFieldAttribute.Length > 0 && pio.GetValue(t, null).ToString() != pio.GetValue(oldT, null).ToString())
                        {
                            SetValue += ((DataFieldAttribute)objDataFieldAttribute[0]).FieldName + "=" + "@" + ((DataFieldAttribute)objDataFieldAttribute[0]).FieldName + ",";
                            paras.Add(new SqlParameter("@" + ((DataFieldAttribute)objDataFieldAttribute[0]).FieldName, pio.GetValue(t, null)));
                        }
                    }

                    SetValue = SetValue.TrimEnd(,);
                    sql.Append(SetValue);
                    sql.Append(Where);
                    paras.Add(new SqlParameter("@ID", primarykey));
                    i = SqlHelper.ExecuteNonQuery(tran, CommandType.Text, sql.ToString(), paras.ToArray());
                    return i;
                }
                else
                {
                    tran.Rollback();
                    return -2;
                }


            }
            catch (Exception)
            {
                tran.Rollback();
                return -1;
                throw;
            }
        }

        /// <summary>
        /// 带事务的删除方法
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public int DeleteByTran(T t)
        {
            int i = 0;
            int primarykey = t.ID;
            Type mytype = t.GetType();
            string TableName = mytype.Name;
            string Where = "] where ID =@ID";
            string sql = "DELETE FROM [" + TableName + Where;
            try
            {
                i = SqlHelper.ExecuteNonQuery(tran, CommandType.Text, sql, new SqlParameter("@ID", primarykey));
                return i;
            }
            catch (Exception)
            {
                tran.Rollback();
                return -1;
                throw;
            }

        }

        /// <summary>
        /// 带事务和条件的删除方法
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public int DeleteByTran(T t, string where)
        {
            if (where.IndexOf("1=1") > 0)
            {
                return -1;
            }
            int i = 0;
            string Where = "] where " + where;
            string sql = "DELETE FROM [" + t.TableName + Where;
            try
            {
                i = SqlHelper.ExecuteNonQuery(tran, CommandType.Text, sql, null);
                return i;
            }
            catch (Exception)
            {
                tran.Rollback();
                return -1;
                throw;
            }

        }

        /// <summary>
        /// 提交事务
        /// </summary>
        /// <returns></returns>
        public void CommitTran()
        {
            try
            {
                tran.Commit();
                conn.Close();

            }
            catch (Exception)
            {
                tran.Rollback();
                conn.Close();
                throw;
            }
            finally
            {
                tran.Dispose();
                conn.Dispose();
            }

        }

        /// <summary>
        /// 回滚事务
        /// </summary>
        public void RollBackTran()
        {
            try
            {
                tran.Rollback();
            }
            catch (Exception)
            {

                throw;
            }
        }


    }
}
View Code

 

好了,整个ORM就写完了,这样我们数据处理的类就写完了!

三:Domain层

ORM写完后,因为不同的表可能在不同的库中,所以ZeroORM还不能直接拿来用,需要在上面隔离一层,我们这里选择最简单的方式,大牛勿喷。

首先写一个Repository基类(这里就不抽象类了),代码如下

技术分享
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Zero.Domain.Abstract;
using Zero.Infrastructure.IBase;

namespace Zero.Domain.Concrete
{
    public class ConcreteBase<T> where T : IDataBase
    {
        public Zero.Infrastructure.Conntion.ZeroORM<T> DbHelper;

        public ConcreteBase()
        {
            DbHelper = new Infrastructure.Conntion.ZeroORM<T>();
        }

        public string SqlConnctionString { get { return DbHelper.SqlConnctionString; } set { DbHelper.SqlConnctionString = value; } }

        public List<T> GetAllList(T t)
        {
            List<T> ubiList = new List<T>();
            ubiList = DbHelper.Select(t);
            return ubiList;
        }

        public bool Insert(T t)
        {
            int i = 0;
            i = DbHelper.Insert(t);
            return i > 0;
        }

        public bool Update(T t)
        {
            int i = 0;
            i = DbHelper.Update(t);
            return i > 0;
        }

        public bool Delete(T t)
        {
            int i = 0;
            i = DbHelper.Delete(t);
            return i > 0;
        }

        /// <summary>
        /// 带事务的插入方法
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public bool InsertByTran(T t)
        {
            if (DbHelper.tran == null)
            {
                DbHelper.BeginTran();
            }
            int i = DbHelper.InsertByTran(t);
            return i > 0;
        }

        /// <summary>
        /// 带事务的更新方法
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public bool UpdateByTran(T t)
        {
            if (DbHelper.tran == null)
            {
                DbHelper.BeginTran();
            }
            int i = DbHelper.UpdateByTran(t);
            return i > 0;
        }

        /// <summary>
        /// 带事务的删除方法
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public bool DeleteByTran(T t)
        {
            if (DbHelper.tran == null)
            {
                DbHelper.BeginTran();
            }
            int i = DbHelper.DeleteByTran(t);
            return i > 0;
        }

        /// <summary>
        /// 带事务和条件的删除方法
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public bool DeleteByTran(T t, string where)
        {
            if (DbHelper.tran == null)
            {
                DbHelper.BeginTran();
            }
            int i = DbHelper.DeleteByTran(t, where);
            return i > 0;
        }

 

        /// <summary>
        /// 
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public void RollBackTran()
        {
            DbHelper.RollBackTran();

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public void BeginTran()
        {
            DbHelper.BeginTran();

        }


        /// <summary>
        /// 提交事务 提交成功返回"";失败返回错误信息
        /// </summary>
        /// <returns>提交成功返回"";失败返回错误信息</returns>
        public string CommitTran()
        {
            if (DbHelper.tran != null)
            {
                try
                {
                    DbHelper.CommitTran();
                    return "";
                }
                catch (Exception e)
                {
                    return e.ToString();
                    throw;
                }
            }
            else
            {
                return "不存在可提交的事务";
            }
        }


        /// <summary>
        /// 根据主键ID查询结果,返回T
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public T SelectByID(string id, T t)
        {
            if (id != "")
            {

                return DbHelper.SelectByID(int.Parse(id), t);
            }
            else
            {
                return null;
            }
        }

    }
}
View Code

 

然后去写Repository类和IRepository接口

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Zero.Domain.Entities;

namespace Zero.Domain.Abstract
{
    public interface IUserRepository
    {
        User GetEntity();
        IQueryable<User> Users { get; }
    }
}

 

实现类:

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using Zero.Domain.Abstract;
using Zero.Domain.Entities;

namespace Zero.Domain.Concrete
{
    public class UserRepository : ConcreteBase<User>, IUserRepository
    {
        public User GetEntity()
        {
            return new User();
        }
        public IQueryable<User> BaseTitleTypes
        {
            get { return GetAllList(GetEntity()).AsQueryable(); }
        }

        public UserRepository()
            : base()
        {
            SqlConnctionString = ConfigurationManager.ConnectionStrings["ZeroTest"].ConnectionString;//获取连接字符串
        }


    }
}

 

然后去数据库建表

技术分享
链接字符串的位置写的有点蠢,不过先这样做吧,一切已快速为目的

现在,所有的准备工作都做完了,开始测试一下数据交互是否有问题!

在Zero项目中建一个Index控制器

技术分享

技术分享

然后右键Index添加视图。先不做IOC解耦,引用Domain层和基础设施层。

添加如下代码

//
  // GET: /Index/

  public ActionResult Index()
  {

      UserRepository us = new UserRepository();
      bool b =us.Insert(new Domain.Entities.User { UserName = "Ambre" });
      if (b)
      {
          var ListEntity = from o in us.Users
                           select o;
          return Json(ListEntity, JsonRequestBehavior.AllowGet);
      }
      else
      {
          return Content(b.ToString());
      }
  }

 

然后去改下路由设置

技术分享

启动项目

技术分享

好了,完成!下篇文章将写如何快速的将IOC应用到项目中,然后前端类似于EasyUi的grid控件如何编写。

谢谢大家,喜欢的话,点个赞,这可是我的处女文呢!

MVC实战起步(一):一个简易框架的搭建

标签:

原文地址:http://www.cnblogs.com/Ambre/p/4955680.html

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