关于框架的使用文档,有什么不足的地方,还需大家指出,谢谢。
SQL类的创建及调用
目前采用 DbProviderFactory 实现 SQL 的方式完成快速开发。
本篇文章只说:Sql Server 数据库的,其他数据库,请在开源仓库查看。
采用最新 2.0.1 版本,实现的架构
(注明:这里使用的开发工具是 vs 2019 )
以下的写法,请先引用框架,Tool.Net 框架
项目地址:AdminManager
创建
新建一个类,名字随意,这个很简单,就不再赘述,不懂的请百度。
然后会生成如下:文件
using System;
using System.Collections.Generic;
namespace Test.DBA
{
public class TestDB
{
}
}
这个是系统为你生成的,这个时候我们只需要引用框架的命名空间。
using Tool;
using Tool.SqlCore;
然后将TestDB类名后的继承改为 BaseDataProvider,这个时候回显示报错,你需要实现抽象类,
如图:
根据你的需要选择实现其中的一个。我实现了第二个,如图:
这里的 connString 是链接数据的连接,DbProviderType 枚举是选择连接的数据库。
SqlServerProvider 是一个自己实现的类,示例如下:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Text;
using Tool;
using Tool.SqlCore;
/// <summary>
/// 获取相关SqlServer对应的数据类型
/// </summary>
public class SqlServerProvider : IDbProvider
{
/// <summary>
/// 根据<see cref="Type"/>类型获取对应的类型
/// </summary>
/// <param name="t"><see cref="Type"/>类型</param>
/// <returns>类型</returns>
public Enum ConvertToLocalDbType(Type t)
{
string key = t.ToString();
switch (key)
{
case "System.Boolean":
return SqlDbType.Bit;
case "System.DateTime":
return SqlDbType.DateTime;
case "System.Decimal":
return SqlDbType.Decimal;
case "System.Single":
return SqlDbType.Float;
case "System.Double":
return SqlDbType.Float;
case "System.Byte[]":
return SqlDbType.Image;
case "System.Int64":
return SqlDbType.BigInt;
case "System.Int32":
return SqlDbType.Int;
case "System.String":
return SqlDbType.NVarChar;
case "System.Int16":
return SqlDbType.SmallInt;
case "System.Byte":
return SqlDbType.TinyInt;
case "System.Guid":
return SqlDbType.UniqueIdentifier;
case "System.TimeSpan":
return SqlDbType.Time;
case "System.Object":
return SqlDbType.Variant;
}
return SqlDbType.Int;
}
/// <summary>
/// 验证对象信息,并填充进<see cref="SqlCommand"/>集合中
/// </summary>
/// <param name="cmd">参数</param>
public void DeriveParameters(IDbCommand cmd)
{
if (cmd is SqlCommand)
{
SqlCommandBuilder.DeriveParameters(cmd as SqlCommand);
}
}
/// <summary>
/// 获取插入数据的主键ID(SQL)
/// </summary>
/// <returns></returns>
public string GetLastIdSql()
{
return "SELECT SCOPE_IDENTITY()";
}
/// <summary>
/// 绑定数据
/// </summary>
/// <param name="paraName">键</param>
/// <param name="paraValue">值</param>
/// <param name="direction">指定查询内的有关 <see cref="DataSet"/> 的参数的类型。</param>
/// <param name="paraType">类型</param>
/// <param name="sourceColumn">源列</param>
/// <param name="size">大小</param>
/// <returns></returns>
public void GetParam(ref DbParameter paraName, object paraValue, ParameterDirection direction, Type paraType, string sourceColumn, int size)
{
SqlParameter sqlParameter = paraName as SqlParameter;
if (paraType != null)
{
sqlParameter.SqlDbType = this.ConvertToLocalDbType(paraType).ToVar<SqlDbType>();
}
}
/// <summary>
/// 就是这个符号'@'
/// </summary>
public string ParameterPrefix
{
get
{
return "@";
}
}
}
以上完成了,整个SQL 部分的搭建,是不是很简单了?下面我们来实现对数据库的操作。
查询:
写一个查询:
using System;
using System.Collections.Generic;
using System.Data;
using UniversalFrame;//缺少了引用
using UniversalFrame.SqlKernel;//引用它
namespace Test.DBA
{
public class TestDB : BaseDataProvider
{
/// <summary>
/// 这是为了给父类链接语句
/// </summary>
/// <param name="connString"></param>
public TestDB(string connString) : base(connString, DbProviderType.SqlServer) //记住要实现的父类
{
}
/// <summary>
/// 获取数据
/// </summary>
/// <returns></returns>
public DataSet GetVote(int Count)
{
//第一种
var data1 = Database.ExecuteDataset(string.Format("SELECT Top({0}) * FROM [vote] WITH(NOLOCK)", Count));
//第二种
var data2 = Database.ExecuteDataset("SELECT Top(" + Count + ") * FROM [vote] WITH(NOLOCK)");
//第三种
var data3 = Database.ExecuteDataset(CommandType.Text, "SELECT Top(@Count) * FROM [vote] WITH(NOLOCK)", Database.MakeParam("Count", Count, ParameterDirection.Input));
//第四种
var data4 = Database.ExecuteDataset("SELECT Top(@Count) * FROM [vote] WITH(NOLOCK)", new { Count });
var data5 = Database.QueryList<vote>("SELECT Top(@Count) * FROM [vote] WITH(NOLOCK)", new { Count });
return data4;
}
}
}
以上是我给出的几种查询方法,大家请根据实际情况改动。还有很多就不写出来了,具体看注释。
新增:
其中一种方法如下:
/// <summary>
/// 通过语句新增
/// </summary>
/// <returns></returns>
public int AddVote(vote vote)
{
return Database.ExecuteNonQuery(" INSERT INTO[dbo].[vote]([Name],[Telephone],[Mail],[Img],[Ctime],[tops],[Address],[UID])VALUES" +
"(@Name,@Telephone,@Mail,@Img,@Ctime,@tops,@Address,@UID)", new { vote.Name, vote.Telephone, vote.Mail, vote.Img, vote.Ctime, vote.tops, vote.Address, vote.UID });
}
删除:
其中一种方法如下:
/// <summary>
/// 通过语句删除
/// </summary>
/// <returns></returns>
public int DeleteVote(int id)
{
return Database.ExecuteNonQuery(" DELETE FROM [dbo].[vote] WHERE ID = @id", new { id });
}
/// <summary>
/// 通过语句删除 方案2 高效
/// </summary>
/// <returns></returns>
public int DeleteVote(int id)
{
return Database.Delete(TableName: "[dbo].[vote]", where: "ID = @id", new { id });
}
修改:
其中一种方法如下:
/// <summary>
/// 通过语句修改
/// </summary>
/// <returns></returns>
public int UpdateVote(vote vote)
{
return Database.ExecuteNonQuery(" UPDATE [dbo].[vote] SET [Name] = @Name,[Telephone] = @Telephone,[Mail] = @Mail,[Img] = @Img,[Ctime] = @Ctime,[tops] = @tops,[Address] = @Address,[UID] = @UID WHERE ID = @ID", new { vote.Name, vote.Telephone, vote.Mail, vote.Img, vote.Ctime, vote.tops, vote.Address, vote.UID, vote.ID });
}
/// <summary>
/// 通过语句修改 方案2 高效
/// </summary>
/// <returns></returns>
public int UpdateVote(vote vote)
{
return Database.Update(TableName: "[dbo].[vote]", where: "ID = " + id, new { vote.Name, vote.Telephone, vote.Mail, vote.Img, vote.Ctime, vote.tops, vote.Address, vote.UID });
}
以上都是最原始的增删改查操作,下面是存储过程的使用和分页。
存储过程:
举例如下:
/// <summary>
/// 执行存储过程
/// </summary>
/// <param name="Count">获取的条数</param>
/// <returns></returns>
public Message NET_GetVote(int Count)
{
return Database.GetMessageForDataSet("NET_GetVote", new { Count }, Database.MakeOutParam("strErrorDescribe", typeof(string), 127));
}
strErrorDescribe 这个字段是返回信息的。
Message 这个类是,存储过程执行完后的所有信息,都会返回在里面。
里面有多种写法,这里就不举例了。
分页:
举例如下:
/// <summary>
/// 获取分页列表
/// </summary>
/// <param name="whereQuery">条件语句</param>
/// <param name="pageIndex">页数</param>
/// <param name="pageSize">条数</param>
/// <param name="fields">查询的字段名</param>
/// <returns></returns>
public PagerSet GetPager(string whereQuery, int pageIndex, int pageSize, string[] fields)
{
const string orderQuery = "ORDER By Ctime DESC ";//排序顺序
PagerParameters pager = new PagerParameters("vote", orderQuery, whereQuery, pageIndex,
pageSize, fields);
return GetPagerSet(pager);
}
PagerParameters 这个类是分页操作类。用于分页查询,相关操作。
下面将写一种特殊对象,他是通过对单表的操作。实现高效的增删改查。
废话不多说直接上代码:
using System;
using System.Collections.Generic;
using System.Data;
using UniversalFrame;//缺少了引用
using UniversalFrame.SqlKernel;//引用它
namespace Test.DBA
{
public class TestDB : BaseDataProvider
{
/// <summary>
/// 获取表的完全对象
/// </summary>
private ITableProvider ITableVote;
/// <summary>
/// 这是为了给父类链接语句
/// </summary>
/// <param name="connString"></param>
public TestDB(string connString) : base(connString, DbProviderType.SqlServer) //记住要实现的父类
{
//表名
ITableVote = GetTableProvider("vote");
}
/// <summary>
/// 新增记录 第一种方式
/// </summary>
/// <returns></returns>
public int SetVote(vote vote)
{
//简化写法
//这个获取相关参数对象
Dictionary<string, object> keyValues = vote.ToDictionary();
keyValues.Remove("ID");//删除ID因为他无需添加
//使用这个写法表达
return ITableVote.Insert(keyValues);
}
/// <summary>
/// 新增记录 第二种方式
/// </summary>
/// <returns></returns>
public int SetVote1(vote vote)
{
//使用这个写法表达
return ITableVote.Insert(new { vote.Name, vote.Telephone, vote.Mail, vote.Img, vote.Ctime, vote.tops, vote.Address, vote.UID });
}
//下面我就简单例出,方法:
ITableVote.Get();//查询
ITableVote.GetObject<T>();//查询返回实体
ITableVote.GetObjectList<T>();//查询返回实体数组
ITableVote.Update();//修改
ITableVote.Delete();//删除
}
}
关于使用
直接上示例:
using UniversalFrame;//这个时候,我们引用他。
using UniversalFrame.Web;
namespace TestWeb
{
/// <summary>
/// test 的摘要说明
/// </summary>
public class Test : ApiAshx
{
[Ashx(State = Ashx_State.Post)]
public void Vote(int Count = 20)
{
TestDB _TestDB = new TestDB("server=.;uid=sa;pwd=123456;database=test;Pooling=true");
var data = _TestDB.GetVote(Count);
Json(data.ToJSON()[0]);//DataSet对象转JSON,这个是方法。[0]是指第一张表
}
}
}
只是一个简易的示例。
运行结果
图一:
以上是SQL部分的示例,感谢您的阅读,有何见解,请留言,也希望大家能提出优化的方向,在此谢过了。