2022-10-23 338
今天来晒晒我的通用数据访问层。
写了很多年的数据库项目,数据访问嘛,一直是用业务实体+存储过程的方式,因此经常会写很多调用存储过程的代码。这些代码用Ado.net如何写,我想大家应该都知道:创建Connection, 创建Command, 给命令参数一个一个赋值,然后调用,调用完成后,如果有输出参数,则要读出来,如果有结果集,则要将结果集转换成自己的实体列表,这个过程也是非常机械化的。总之,调用任何存储过程都需要这样一堆类似的代码。
我是个喜欢最求完美的人,自然不喜欢每个项目都有这样一堆机械代码的存在,于是经过不断的重构代码,慢慢的就形成了自己的通用数据访问层。
我的通用数据访问层具有以下特点:
设计目标:调用存储过程,不管输入参数多么复杂,不管有多少输出参数,包含转换一个结果集到实体列表,只需要一行C#代码。
1. 示范代码,简单地调用单个存储过程
C#实体类型,成员与数据库表对应,这里就不给出表结构截图了。
///<summary> ///表示一个商品对象的实体类 ///</summary> publicsealedclassProduct { publicintProductID{get;set;} publicstringProductName{get;set;} publicintCategoryID{get;set;} publicstringUnit{get;set;} publicdecimalUnitPrice{get;set;} publicintQuantity{get;set;} //仅当加载详细信息(单个实体)时才加载它。加载列表时忽略这个字段。 [ItemField(OnlyLoadAll=true)] publicstringRemark{get;set;} }
存储过程-更新商品信息
createprocedure[dbo].[UpdateProduct]( @ProductNamenvarchar(50), @CategoryIDint, @Unitnvarchar(10), @UnitPricemoney, @Quantityint, @Remarknvarchar(max), @ProductIDint ) as updateProducts setProductName=@ProductName, CategoryID=@CategoryID, Unit=@Unit, UnitPrice=@UnitPrice, Quantity=@Quantity, Remark=@Remark whereProductID=@ProductID;
C#调用代码
publicboolUpdateProduct(Productproduct) { return(FishBLLHelper.CallSpExecuteNonQuery("UpdateProduct",product)>0); }
存储过程-获取商品列表,支持分页
createprocedure[dbo].[GetProductByCategoryId]( @CategoryIDint, @PageIndexint=0, @PageSizeint=20, @TotalRecordsintoutput ) as begin declare@ResultTabletable ( RowIndexint, ProductIDint, ProductNamenvarchar(50), CategoryIDint, Unitnvarchar(10), UnitPricemoney, Quantityint ); insertinto@ResultTable selectrow_number()over(orderbyProductIDasc)asRowIndex, p.ProductID,p.ProductName,p.CategoryID,p.Unit,p.UnitPrice,p.Quantity fromProductsasp whereCategoryID=@CategoryID; select@TotalRecords=count(*)from@ResultTable; select* from@ResultTable whereRowIndex>(@PageSize*@PageIndex)andRowIndex<=(@PageSize*(@PageIndex+1)); end;
C#调用代码
publicList<Product>GetProductByCategoryId(intcategoryId,refintpageIndex,intpageSize,outintrecCount) { returnFishBLLHelper.CallSpGetDataItemListPaged<Product>("GetProductByCategoryId", refpageIndex,pageSize,outrecCount,categoryId); }
2. 示范代码,以事务方式调用多个存储过程
C#实体类型,成员与数据库表对应,这里就不给出表结构截图了。
publicsealedclassOrderItem { publicintOrderID{get;set;} publicint?CustomerID{get;set;} publicDateTimeOrderDate{get;set;} publicdecimalSumMoney{get;set;} [ItemField(OnlyLoadAll=true)]//仅当加载详细信息时才加载它。 publicstringComment{get;set;} publicboolFinished{get;set;} publicstringCustomerName{get;set;} [ItemField(IgnoreLoad=true)]//不加载这个成员 publicList<OrderDetail>Detail; } publicsealedclassOrderDetail { publicintOrderID{get;set;} publicintProductID{get;set;} publicdecimalUnitPrice{get;set;} publicintQuantity{get;set;} }
三个存储过程,用于插入主表,子表,刷新总金额
createprocedure[dbo].[InsertOrder]( @CustomerIDint=null, @SumMoneymoney, @Commentnvarchar(300), @OrderIDintoutput ) as begin insertintoOrders(CustomerID,OrderDate,SumMoney,Comment) values(@CustomerID,getdate(),@SumMoney,@Comment); set@OrderID=scope_identity(); end; createprocedure[dbo].[InsertOrderDetail]( @OrderIDint, @ProductIDint, @Quantityint ) as declare@Pricemoney; select@Price=(selectUnitPricefromProductswhereProductID=@ProductID); insertinto[OrderDetails](OrderID,ProductID,UnitPrice,Quantity) values(@OrderID,@ProductID,@Price,@Quantity); createprocedure[dbo].[RefreshOrderSumMoney]( @OrderIDint ) as declare@SumMoneymoney; select@SumMoney=(selectsum(UnitPrice*Quantity)from[OrderDetails]whereOrderID=@OrderID); updateOrderssetSumMoney=@SumMoneywhereOrderID=@OrderID;
说明:以上三个存储要求先调用InsertOrder,然后获取新的OrderID后,才能调用后面二个。下面来看看在C#中该如何调用这三个存储过程吧。
C#调用代码
publicintAddOrder(OrderItemorder) { //以事务的方式创建一个FishDbContext对象,将使用默认的连接字符串 using(FishDbContextdb=newFishDbContext(true)){ //添加记录到表Orders,同时获取新产生ID FishBLLHelper.CallSpExecuteNonQuery(db,"InsertOrder",order); //为订单明细设置OrderId,并添加到表[OrderDetails] order.Detail.ForEach(x=>{ x.OrderID=order.OrderID; FishBLLHelper.CallSpExecuteNonQuery(db,"InsertOrderDetail",x); }); //刷新订单总金额。 FishBLLHelper.CallSpExecuteNonQuery(db,"RefreshOrderSumMoney",null,order.OrderID); //提交事务。 db.CommitTransaction(); returnorder.OrderID; } }
好了,示例就写到这里,方不方便嘛,自己觉得好用就行。
今天先不谈ORM工具,我们只谈存储过程,下次我会写个关于性能测试的文章来专门谈ORM。
原文链接:https://77isp.com/post/7646.html
=========================================
https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。
数据库技术 2022-03-28
网站技术 2023-01-07
网站技术 2022-11-26
网站技术 2022-11-17
Windows相关 2022-02-23
网站技术 2023-01-14
Windows相关 2022-02-16
Windows相关 2022-02-16
Linux相关 2022-02-27
数据库技术 2022-02-20
小游客游戏攻略网游戏攻略网 2024年07月26日
抠敌 2023年10月23日
嚼餐 2023年10月23日
男忌 2023年10月22日
瓮仆 2023年10月22日
扫码二维码
获取最新动态