【实习】刚入职,公司要求完成两个任务,任务要求使用存储过程和事务,其中一个问题要获取存储过程的查询结果集。经过多方查找和自己的实践,终于找到了方法。这里记录一下。
看到的这篇文章中给出的例子是查询单个表的所有数据,但是我的要求是多表查询并获取其中的几个字段。而且我是使用POCO(POCO是指Plain Old Class Object,也就是最基本的CLRClass),还是和示例有诸多不同。这里我结合文章中的示例和自己的尝试,解决了这个问题
首先建立存储过程 可以看到 这里我只需要sn.jewelry_type ,tr.[History Sign2] ,SUM(his.[Actual_Selling_Price]) AS Summary这三个字段
CREATE PROCEDURE dbo.SP_Branch_Month_Sells @branchCode INT, @transactionDate DATE AS SELECT sn.jewelry_type AS JewelryType, tr.[History Sign2] AS HistorySign2, SUM(his.[Actual_Selling_Price]) AS Summary FROM dbo.History his INNER JOIN dbo.[stock nature] sn ON his.[Stock Type] = sn.stock_type AND his.[Stock Group] = sn.stock_group INNER JOIN dbo.[History Tran Code] tr ON his.[Tran Code] = tr.[History Tran Code] WHERE his.[Branch Code From] = @branchCode AND sn.[jewelry_type] IN ( 1, 2, 3 ) AND tr.[History Sign2] IN ( 2, 7, 8, -2, -7, -8 ) AND DateDiff(mm,his.[Transaction Date],@transactionDate)=0 GROUP BY sn.jewelry_type, tr.[History Sign2] GO
然后根据这三个字段建立对应的实体类和配置类,虽然在数据库中并没有对应的表,这里的实体类只是作为存储过程的结果集的对应实体
public class SellEntity { public Int16 JewelryType { get; set; } public Int16 HistorySign2 { get; set; } public decimal Summary { get; set; } } public class SellConfig:EntityTypeConfiguration<SellEntity> { public SellConfig() { //EF 需要每个表都有一个键,这里的JewelryType并没有实际键的意义,只是为满足EF的要求 HasKey(u => u.JewelryType); Property(u => u.JewelryType).HasColumnName("JewelryType"); Property(u => u.HistorySign2).HasColumnName("HistorySign2"); } }
然后就可以使用EF调用存储过程来获取结果集并和实体类对应起来,注意这里我使用了DTO,
public class SellDTO { public int JewelryType { get; set; } public int HistorySign2 { get; set; } public decimal Summary { get; set; } } public SellDTO[] GetSells(int branchCode, DateTime monthDate) { using(TrainContext ctx = new TrainContext()) { var paramters = new SqlParameter[] { new SqlParameter("branchCode",SqlDbType.Int) { Value=branchCode}, new SqlParameter("transactionDate", SqlDbType.Date) { Value =monthDate.ToShortDateString() } };
//EO转换成DTO return ctx.Sells.SqlQuery("EXEC dbo.SP_Branch_Month_Sells @branchCode,@transactionDate)", paramters) .ToList().Select(u=>new SellDTO() { JewelryType = u.JewelryType, HistorySign2 = u.HistorySign2, Summary = u.Summary }).ToArray(); } }
这里是DAL层的代码,BLL层只是对参数做转发
public class SellBLL { public SellDTO[] GetSellByMonthAndBranchCode(int branchCode, DateTime monthDate) { var sellDAL = new SellDAL(); return sellDAL.GetSells(branchCode, monthDate); } }
下面进行单元测试:
[TestClass] public class SellTests { [TestMethod] public void GetSellByMonthAndBranchCodeTest() { SellBLL sellBLL = new SellBLL(); var sells = sellBLL.GetSellByMonthAndBranchCode(3158, DateTime.Today.AddDays(-26)); } }
测试结果
拿到结果集 和直接在数据库查询的结果一致。
成功