QQZiFramework笔记:开始使用DBContext

系统运行前初始化DBContext

WEB.Config中配置连接串

<add name="DefaultConnection" connectionString="Data Source=192.168.1.58;Initial Catalog=CirclesFinancial;User ID=sa;Password=123456" providerName="System.Data.SqlClient"/>
<add name="LogConnection" connectionString="Data Source=192.168.1.58;Initial Catalog=CirclesFinancial;User ID=sa;Password=123456;Pooling=true;Max Pool Size = 300; Min Pool Size=0; Connection Lifetime = 300;packet size=1000;" providerName="System.Data.SqlClient" />
LogConnection为日志的数据库,会记录访问过程Sql语句的执行,需要log4net配置


 log4net.Config.XmlConfigurator.Configure();
      
 //Database配置
 ConnectionStringSettings connSet = System.Configuration.ConfigurationManager.ConnectionStrings["DefaultConnection"];
 string filePath= Server.MapPath("~/Content/Permission.json");
 QQZiFramework.DataBase.DBContext.LoadConfigFromFile(filePath, new DBContextConfig(connSet, "CirclesFinancial.Modals.{0},CirclesFinancial.Modals") { LogSql = 2 });
 ConnectionStringSettings logConnSet = System.Configuration.ConfigurationManager.ConnectionStrings["LogConnection"];
 QQZiFramework.DataBase.DBContext.LogDBConfig = new DBContextConfig(logConnSet, null);
 QQZiFramework.MyHttpUtility.DefaultCertificatePath = Server.MapPath("~/Content");

DBContext.LoadConfigFromFile 方法初始化配置,filepath是一个json文件,里面是访问的sql配置(按需要配置),后面会讲配置文件写法

MyHttpUtility.DefaultCertificatePath 方法,MyHttpUtility是封装的一个httpWebRequest类,get,post,download等方法,添加https的处理,并且对cooike管理的好些,本属性是初始化的证书存放的目录,在某些https访问中会需要证书,项目中不使用的话可不写。


上一篇介绍了DBContext在使用的时候,需要在using的过程中,并且用它来处理数据访问

using (DBContext context = new DBContext(true))  
    {  
        context.GetBusiness<RMBDrivers>().SaveSchedule(id, array);  
        context.Commit();  
    }  

在发生异常的时候会调用context.Dispose()方法,释放连接,如果有事务,会回滚。

需要使用数据访问,需要先了解个概念,数据库的查询是如果被映射到实体的


实体数据表
public class DBEntity{
  public  in ID { get;set; }
public string Name{get;set}
}                              
DBEntity表
ID int
Name varchar(255)

要求:

实体必需继承QQZiFramework.DataBase.IDBEntity父类(非接口)

IDBEntity中有一些公用的方法,ParseFromTable,ParseFromTableRow,ToJson等,根据名字能知道用途,重点要讲一下几个自定义属性

DBTableAttribute:写在实体类上,用来定义实体对应的表,IsVirtual:是否是虚拟的表(不存在于数据库中)

[DBTable(TableName = "A0_Order",IsVirtual=False)]
public class Order : IDBEntity
{
}


DBFieldAttribute:写在属性上,用来定义对应的列名,用途(Usage属性,主键,外键,是否包含在默认的查询中等),不定义则默认为同时的表字段

Usage:(PrimaryKey:主键;ForeignKey:外键;MarkDelete:删除状态标记,比如Status;NoField:非表字段,不用于默认查询(虚拟实体除外))

[DBField(Usage=DBFieldUsage.NoField)]
 public int BusinessId { get; set; }

[DBField(Usage = DBFieldUsage.ForeignKey,ForeignTable="A0_Area", ForeignTableField="Code")]
 public string ParentCode { get; set; }


JsonConverter:被序列化的时候格式化处理类,一般用在日期,有UnixTimeConverter和UnixDateConverter,代理时间和日期

[JsonConverter(typeof(UnixTimeConverter))]
public DateTime PayDate { get; set; }

DefaultValue:初始化实体时候,被默认赋的值,用来做值类型的为空处理, int类型用DefaultNullValue,double,long,decimal:DefaultDoubleValue

[DefaultValue(DefaultNullValue)]
public int Status { get; set; }


所有的表必需要有主键,sqlserver目前必需要用标识列,也就是自增列。实体中需要定义主键,比如

 /// <summary>
 /// 用户编号
/// </summary>
[DBField(Usage = DBFieldUsage.PrimaryKey)]
public int UserId { get; set; }


实体定义就继事,就能在程序中使用DBContext来操作该表了

QuerySingle<T>查询单条数据返回实体
QueryMany<T>查询多笔数据返回实体集合
QueryTree 查询并返回树型结构实体,需要继承ITreeDBEntity
QueryTable查询语句返回DataTable
QueryReader查询语句返回DataReader
ExecScalar查询单条数据,返回第一行第一列(查询单列)
ExecuteCommand执行语句
Exists<T>判断是否存在某个条件的记录,对应Sql的exists查询
Count<T>查询指定条件的记录行
Update<T>更新指定表的某些列
DoSave根据实体的值,保存到表中,如果主键有值,则为更新
DoDelete<T> 根据主键删除

QuerySingle:查询单条数据返回实体

具有多个重载,列出常用的三个

/// <summary>
/// 查询并返回单个实体
/// </summary>        
/// <param name="primarkVal">主键值</param>
/// <param name="throwWhen">没有数据是否抛异常,Null:不抛,空字符串则抛出默认的消息,也可以是传具体的消息内容</param>
public T QuerySingle<T>(string primarkVal, string throwWhen = null) where T : IDBEntity

/// <summary>
/// 查询并返回单个实体
/// </summary>        
/// <param name="where">查询条件(动态类)</param>
/// <param name="permission"></param>
/// <param name="queryFilter">查询列(实体属性)过滤,以逗号隔开</param>        
/// <param name="throwWhen">没有数据是否抛异常,Null:不抛,空字符串则抛出默认的消息,也可以是传具体的消息内容</param>
/// <returns></returns>
public T QuerySingle<T>(object where, string permission, string queryFilter, string throwWhen) where T : IDBEntity

/// 查询
/// </summary>
/// <param name="permission"配置项名称><pre name="code" class="csharp">配置项名称
</param>/// <param name="primarkVal">主键值</param>/// <param name="queryFilter">查询列(实体属性)过滤,以逗号隔开</param>/// <param name="throwWhen">没有数据是否抛异常,Null:不抛,空字符串则抛出默认的消息,也可以是传具体的消息内容</param>/// <param name="defaultNullValue">值类型属性为空是否标记为DefaultNullValue</param>/// <returns></returns>public T QuerySingle<T>(string permission, int primarkVal, string queryFilter, string throwWhen, bool defaultNullValue) where T : IDBEntity

 

permission配置项后面讲,where是一个动态类,比如new {ID=10086} ,也可以传复杂的条件,比如 new {name ="like '%吕%'", Status = "> 1"} 

QueryMany:查询多笔数据返回实体集合

/// <summary>
/// 查询结果返回List
/// </summary>
/// <param name="sql">查询的语句</param>
/// <returns></returns>
public List<T> QueryMany<T>(string sql) where T : IDBEntity

/// <summary>
/// 查询结果返回List
/// </summary>
/// <param name="where">查询条件(动态类)</param>
/// <param name="queryFilter">查询列(实体属性)过滤,以逗号隔开</param>
/// <returns></returns>
public List<T> QueryMany<T>(object where, string queryFilter = null) where T : IDBEntity

/// <summary>
/// 查询结果返回List
/// </summary>
/// <param name="where">查询条件(动态类)</param>
/// <param name="permission">配置项名称</param>
/// <param name="queryFilter">查询列(实体属性)过滤,以逗号隔开</param>
public List<T> QueryMany<T>(object where, string permission, string queryFilter) where T : IDBEntity

ExecScalar:查询单条数据,返回第一行第一列(查询单列)

/// <summary>
/// 执行语句返回第一行第一列
/// </summary>
/// <param name="sql"></param>
/// <returns>第一行第一列值,如果是空则为DBNull.Value</returns>
public object ExecScalar(string sql)

/// <summary>
/// 查询某个字段的值
/// </summary>        
/// <param name="fieldName">字段名</param>
/// <param name="primaryKey">主键值</param>
/// <returns>如果字段为空则返回null(注意:不是DBNull.Value)</returns>
public object ExecScalar<T>(string fieldName, int primaryKey)

/// <summary>
/// 查询某个字段的值
/// </summary>        
/// <param name="fieldName">字段名</param>
/// <param name="primaryKey">主键值</param>
/// <returns>如果字段为空则返回null(注意:不是DBNull.Value)</returns>
public object ExecScalar<T>(string fieldName, object where, string throwNull)


DoSave:根据实体的值,保存到表中,如果主键有值,则为更新

/// <summary>
/// 保存对象到表,可以配置文件中设定不允许修改的列NotAllow
/// </summary>
/// <param name="permission">保存配置项</param>
/// <param name="entity">要保存的实体对象</param>
public int DoSave(string permission, IDBEntity entity)
/// <summary>
/// 保存对象到表
/// </summary>        
/// <param name="entity">要保存的实体对象</param>
public int DoSave(IDBEntity entity)


其它:

/// <summary>
/// 查询是否有指定的记录
/// </summary>
/// <param name="permission">查询配置项</param>
/// <param name="entityName">实体名</param>
/// <param name="where">条件动态类</param>
/// <returns></returns>
public bool Exists(string permission, string entityName, object where) 

/// <summary>
/// 查询是否有指定的记录
/// </summary>                
/// <param name="where">条件动态类</param>
/// <returns></returns>
public bool Exists<T>(object where) where T : IDBEntity 

/// <summary>
/// 查询记录数
/// </summary>        
/// <param name="entityName"></param>
/// <param name="where">条件动态类</param>
/// <returns></returns>
public int Count<T>(object where) where T : IDBEntity 

 /// <summary>
/// 更新单个列
/// </summary>        
/// <param name="PropertyName">实体属性</param>
/// <param name="value">值</param>
/// <returns>受影响行数</returns>
public int Update<T>(string PropertyName, object value, int primaryKey) where T : IDBEntity 

/// <summary>
/// 更新单个列
/// </summary>        
/// <param name="columnAndValues">要更新的内容,动态类,比如{Name="吕存库",Sex=1}</param>
/// <param name="primaryKey">主键值</param>
/// <returns>受影响行数</returns>
public int Update<T>(object columnAndValues, int primaryKey) where T : IDBEntity 


举例:

public const string User_NoFound_ErrorMsg = "用户不存在!";

User user = Context.QuerySingle<User>(null, id, "Name", User_NoFound_ErrorMsg);//也可以用*号取出所有的字段
user.Name="吕存库";
Context.DoSave(user);//会更新整个实体,如果属性有值的话
Context.ExecuteCommand("update A0_Users set Name='"+user.Name+"' where userId="+ user.UserId);

//创建新用户
User newUser =new User(){Name="新用户",Mobile="17097913883"};
Context.DoSave(newUser);

//判断用户是否存在:
if(Context.Exists<User>(new{Mobile="17097913883"})){ Console.WriteLine("用户存在"); }

//获取UserId为1的用户的Name
Context.ExecScalar<User>("Name",1);

//查询所有手机号为170开头的用户列表
Context.QueryMany<User>(new {Mobile = "like '170%'"},null,null)



-----------------------------------------------DBContext其它非数据操作的方法----------------------------------------------

GetSystemParam:获取自己在数据库中的参数配置

需要在数据库中有A1_Config表

CREATE TABLE [dbo].[A1_Configs] (
    [Id]         INT           IDENTITY (1, 1) NOT NULL,
    [ParamName]  VARCHAR (64)  NOT NULL,
    [ParamValue] VARCHAR (256) NULL,
    [Remark]     VARCHAR (64)  NULL,
    CONSTRAINT [PK_A1_Configs] PRIMARY KEY CLUSTERED ([Id] ASC)
);

比如:

int ApplyDayBefore = Context.GetSystemParam<int>("ApplyDayBefore", true);//true代表不存在配置是否抛出异常

HasLock:是否存在访问锁定,没有则加锁,有则返回true,需要自己去处理有锁的逻辑,用于异常多次执行的判断,比如银行或者其它支付机构的回调,可能有多次。我们只处理第一次成功的情况。

只按传入的Key做判断,注意唯一性,可以用模块名称+主键的方式

Utility.LogMessage("缴费回调,trxId:" + trxId + ",orderId:" + orderStr);
using (DBContext context = new DBContext())
{
	if (context.HasLock("PayFinish" + orderStr)) {
		Utility.LogMessage("已处理过,不执行!");
		return;
	}
	......
}


StrictModel:严格模式

如果设置DBContext的StrictModel为True,则必需要指定Permission,并且操作的列并且在实体中存在,或者在json配置中存在,比如上面的where条件,mobile ="like '170%'",严格模式下就不能使用,除非有配置


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值