简体   繁体   English

Dapper.Net-QueryMultiple与存储过程一起使用,可返回多个结果

[英]Dapper.Net - QueryMultiple use with stored procedure returning multiple results

I'm new to Dapper.Net and was attempting to write my own micro ORM but, felt after some review that Dapper could achieve my requirements. 我是Dapper.Net的新手,正在尝试编写自己的微型ORM,但是经过一番审查,我觉得Dapper可以满足我的要求。

I've came very close to getting this right but still not there. 我已经很接近解决这个问题了,但仍然没有实现。 I think my current implementation isnt as fast as native Dapper. 我认为我当前的实现不如本地Dapper快。 Please assist and thank you! 请协助,谢谢!

POCOS POCOS

public class CustomerCollections
{
    public decimal CifNo { get; set; }
    public string StatusCode { get; set; }
    public decimal TotalPastDue { get; set; }
    public int PaymentsReturned { get; set; }
    public int DaysPastDue { get; set; }
    public List<CollectionPayment> CollectionPayments { get; set; }

}

public class CollectionPayment
{
    public decimal CifNo { get; set; }
    public decimal AcctRefNo { get; set; }
    public decimal PaymentReferenceNumber { get; set; }
    public decimal PaymentAmount { get; set; }
    public DateTime DueDate { get; set; }
    public DateTime NsfDate { get; set; }
    public CollectionPaymentDetail PaymentDetail { get; set; }
}

public class CollectionPaymentDetail
{
    public decimal PaymentReferenceNumber { get; set; }
    public string PaymentMethodType { get; set; }
    public decimal PaymentAmount { get; set; }
    public decimal InterestAmount { get; set; }
    public decimal PrincipalAmount { get; set; }
    public DateTime DueDate { get; set; }
    public DateTime NsfDate { get; set; }
    public string ReturnCode { get; set; }
    public string AgentUser { get; set; }

}

Here is my stored procedure 这是我的存储过程

ALTER PROCEDURE ULPS.sp_GetCollections
(
    @cifno INT
)
AS
BEGIN

SET NOCOUNT ON;

--Past Due Header Info
SELECT l.cifno AS Cifno
    --, l.acctrefno
    , c.status_code AS StatusCode
    , CASE 
        WHEN LOWER(c.status_code) = 'past due' THEN SUM(l.total_past_due_balance)
        ELSE 0
      END
      AS TotalPastDue
     , SUM(p.num_payments_returned) AS PaymentsReturned
     , CAST(SUM(d.days_past_due) AS INT) AS DaysPastDue
FROM dbo.loanacct l
OUTER APPLY (
    SELECT h.acctrefno, COUNT(tc.transaction_description) AS num_payments_returned  FROM dbo.loanacct_trans_history h
    INNER JOIN dbo.loan_transaction_codes tc
    ON tc.transaction_code = h.transaction_code AND LOWER(tc.transaction_description) = 'nsf fee'
    GROUP BY h.acctrefno
) AS p
LEFT JOIN dbo.loanacct_statuses s
    ON s.acctrefno = l.acctrefno
INNER JOIN dbo.loan_status_codes c
    ON c.status_code_no = s.status_code_no
OUTER APPLY (
    SELECT cifno, acctrefno, days_past_due, open_date FROM dbo.loanacct
) AS d
WHERE p.acctrefno = l.acctrefno
    AND (LOWER(c.status_code) = 'write-off' OR LOWER(c.status_code) = 'past due')
    AND l.status_code_no = 0 --ACTIVE ONLY
    AND l.cifno = @cifno
    AND d.acctrefno = l.acctrefno
    AND d.cifno = @cifno
GROUP BY l.cifno
    , c.status_code

--Past Due Loan List
CREATE TABLE #PastDueLoanList (
    Cifno NUMERIC(10,0)
    , AcctRefNo NUMERIC(10,0)
    , PaymentReferenceNumber NUMERIC(9,0)
    , PaymentAmount NUMERIC(12,2)
    , DueDate DATETIME
    , NsfDate DATETIME
) 
INSERT INTO #PastDueLoanList
SELECT l.cifno AS Cifno 
    , h.acctrefno AS AcctRefNo
    , h.payment_reference_no AS PaymentReferenceNumber
    , SUM(h.payment_amount) AS PaymentAmount
    , h.date_due AS DueDate
    , h.nsf_date AS NsfDate
FROM dbo.loanacct l
INNER JOIN dbo.loanacct_payment_history h
    ON h.acctrefno = l.acctrefno and h.nsf_flag = 1 and h.payment_number <> 0
WHERE l.cifno = @cifno
GROUP BY l.cifno
    , h.acctrefno
    , h.payment_reference_no
    , h.transaction_reference_no
    , h.payment_number
    , h.date_due
    , h.nsf_date 

SELECT * FROM #PastDueLoanList

--Past Due Payment Details
SELECT h.acctrefno AS AcctRefNo
    , h.payment_reference_no AS PaymentReferenceNumber
    , m.payment_method_code AS PaymentMethodType
    , SUM(CASE WHEN h.transaction_code = 0 THEN payment_amount ELSE 0 END) AS PaymentAmount
    , SUM(CASE WHEN h.transaction_code = 206 THEN payment_amount ELSE 0 END) AS InterestAmount
    , SUM(CASE WHEN h.transaction_code = 204 THEN payment_amount ELSE 0 END) AS PrincipalAmount
    , MAX(h.date_due) AS DueDate
    , MAX(h.nsf_date) AS NsfDate
    , 'n/a' AS ReturnCode
    , 'unknown, user' AS AgentUser
FROM dbo.loanacct l (NOLOCK)
INNER JOIN #PastDueLoanList tmp
    ON tmp.AcctRefNo = l.acctrefno
INNER JOIN dbo.loanacct_payment_history h (NOLOCK)
    ON h.acctrefno = l.acctrefno and h.nsf_flag = 1
INNER JOIN dbo.loan_payment_method m (NOLOCK)
    ON m.payment_method_no = h.payment_method_no
GROUP BY h.acctrefno
    , h.payment_reference_no
    , m.payment_method_code
END
GO

This works but not the Dapper way. 这有效,但不是Dapper方式。

public async Task<CustomerCollections> GetCustomerCollections(decimal cifno)
{
    var collections = new CustomerCollections();
    using (var multi = await DbContext.NativeContext().QueryMultipleAsync("ULPS.sp_GetCollections", new { cifno }, commandType: CommandType.StoredProcedure))
    {
        collections = await multi.ReadFirstOrDefaultAsync<CustomerCollections>();
        collections.CollectionPayments = multi.Read<CollectionPayment>().ToList();
        var details = multi.Read<CollectionPaymentDetail>().ToList();
        collections.CollectionPayments.ForEach(c =>
        {
            details.ForEach(d =>
            {
                if (c.PaymentReferenceNumber == d.PaymentReferenceNumber)
                    c.PaymentDetail = d;
            });
        });
    }
    return collections;
}

I would return the resultset as a JSON (if you are on a SQL Server version that supports it, like SQL Server 2016 or above or Azure SQL) and then use the "Custom Type Handling" feature to deserialize JSON into your complex object: 我将结果集作为JSON返回(如果您使用的是支持它的SQL Server版本,例如SQL Server 2016或更高版本或Azure SQL),然后使用“自定义类型处理”功能将JSON反序列化为复杂对象:

https://medium.com/dapper-net/custom-type-handling-4b447b97c620 https://medium.com/dapper-net/custom-type-handling-4b447b97c620

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM