使用EntityFramework调用存储过程并获取存储过程返回的结果集

【实习】刚入职,公司要求完成两个任务,任务要求使用存储过程和事务,其中一个问题要获取存储过程的查询结果集。经过多方查找和自己的实践,终于找到了方法。这里记录一下。

看到的这篇文章中给出的例子是查询单个表的所有数据,但是我的要求是多表查询并获取其中的几个字段。而且我是使用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));
        }
    }

测试结果

拿到结果集 和直接在数据库查询的结果一致。

成功

原文地址:https://www.cnblogs.com/c-supreme/p/9698864.html