Dapper 在使用存储过程更新表后停止拉连接表

Posted

技术标签:

【中文标题】Dapper 在使用存储过程更新表后停止拉连接表【英文标题】:Dapper stopped pulling joined table after updating the table with a stored procedure 【发布时间】:2020-10-13 16:36:45 【问题描述】:

因为我遇到了这个错误

InnerException = "当 IDENTITY_INSERT 设置为 OFF 时,无法在表 'Loan' 中插入标识列的显式值。"

所以我决定改成这个存储过程。

this._context.Loan.FromSqlInterpolated($"Exec CreateNewLoan @CurrencyCode = loan.CurrencyCode, @OperativeAcctNo = loan.OperativeAcctNo, @AmountWrittenOff=loan.AmountWrittenOff, @OriginalLoanAmount=loan.OriginalLoanAmount, @LoanTrfDate=loan.LoanTrfDate, @InterestRate=loan.InterestRate, @LoanAccountNo=loan.LoanAccountNo, @DRCR=loan.DRCR, @CustId=loan.CustId ");

哪个是插入记录成功,插入页面后会重定向到索引页面并调用另一个方法拉取列表并用这个dapper查询显示

public async Task<IEnumerable<Loan>> GetAll(bool includeDeleted, bool showUnapprovedOnly)

    IEnumerable<Loan> loans = null;

    try
    
        using (var conn = new SqlConnection(connectionstring))
        
            await conn.OpenAsync();
            //
            string sql = "Select l.*, c.FirstName_CompanyName from dbo.Loan l left join Customer c on  l.CustId=c.CustId";
            if (!includeDeleted)
            
                sql += " and l.Deleted = 0";
            
            if (showUnapprovedOnly)
            
                sql += " and l.Approved = 0";
            

            loans = await conn.QueryAsync<Loan>(sql);
        
    
    catch (Exception)
    

        throw;
    
    return loans;

Loan 和 customer 表之间存在关系。客户 ID(CustId) 也与存储过程一起插入。我注意到没有显示新插入记录的客户名称。以前的正在显示。不知道为什么新记录不拉客户表\

   public class Loan
    
        public int LoanId  get; set; 

        [Display(Name ="Customer Name")]
        public long CustId  get; set; 

        [NotMapped]
        [Display(Name ="Customer")]
        public string FirstName_CompanyName  get; set; 

        [Display(Name = "Currency Code")]
        [StringLength(10)]
        [Required]
        public string CurrencyCode  get; set; 

        [Display(Name = "Loan Account No.")]
        [Key]
        public string LoanAccountNo  get; set; 

        [Display(Name = "Branch Code")]
        [StringLength(5)]
        public string BranchCode  get; set; 

        [Display(Name = "Amount Written Off")]
        [Required]
        public double? AmountWrittenOff  get; set; 

        [DataType(DataType.Date)]
        [Display(Name = "Loan Tranfer Date")]
        [Required]
        public DateTime? LoanTrfDate  get; set; 

        [Display(Name = "Interest Rate")]
        [Required]
        public double? InterestRate  get; set; 

        [ForeignKey("CustId")]
        public virtual Customer Customer  get; set; 

    

【问题讨论】:

是否通过 CreateNewLoan 存储过程或 NULLdbo.Loan 表中正确插入 CustId > 被插入?如果CreateNewLoan有问题,请分享存储过程SQL代码 是的,CustId 已正确插入,并且 CustId 的列也已插入。其他列显示在视图表上。只有新的客户名称没有显示。 CustId 正在引用客户表。以前的客户名称列显示正确 如果 CustId 被正确插入,那么问题可能与 Dapper 映射有关。请分享读取数据的代码。 这是代码string sql = "Select l.*, c.FirstName_CompanyName from dbo.Loan l left join Customer c on l.CustId=c.CustId"; 在我更改身份之前,此代码工作正常。最初参与此项目的人创建了 CustId 身份,该身份也引用了客户表。后来我发现客户可以多次申请贷款。所以我必须改变它并创建一个新的自动生成的身份。不知道是不是这个原因? 您有正确映射的多映射代码吗?它应该看起来像this example。请分享 Dapper 映射代码 【参考方案1】:

看起来 FirstName_CompanyName 没有映射到任何类属性。 此映射更改应该可以解决问题。

var sql = "Select l.*, c.CustId, c.FirstName_CompanyName as Name from dbo.Loan l left join Customer c on  l.CustId=c.CustId";
var loans = connection.Query<Loan, Customer, Loan>(
        sql,
        (loan, customer) =>
        
            loan.CustomerName = customer?.Name;
            return loan;
        ,
        splitOn: "CustId")
    .Distinct()
    .ToList();

【讨论】:

请检查我更新的问题与贷款类。 Loan 和 Customer 类分别没有 CustomerName 和 Name 该属性。 当我跳过代码时,在第二次迭代中,我得到了customer.FirstName_CompanyName threw an exception of type 'System.NullReferenceException 我已将customer.Name 更新为customer?.Name 以修复NullReferenceException

以上是关于Dapper 在使用存储过程更新表后停止拉连接表的主要内容,如果未能解决你的问题,请参考以下文章

在 Dapper 中执行带参数的存储过程

使用 Dapper (C#) 调用 PostgreSQL 存储过程

使用没有字母参数的 Postgresql 的 Dapper 存储过程

DAL 存储库模式使用 dapper 连接

使用 Dapper 从存储过程中获取字段名称

如何使用 Dapper 检索存储过程的返回值