使用Dapper填充类对象

时间:2018-09-09 19:35:19

标签: c# dapper dapper-extensions

public class Expenses
{
    public Category Category { get; set; }
    public PaymentModes PaymentModes { get; set; }
}

public class Category
{
    public int CategoryID { get; set; }
    public string CategoryName { get; set; }
}

public class PaymentModes
{
    public int PaymentModeID { get; set; }
    public string PaymentMode { get; set; }
}

public class ViewModel
{
   public IEnumerable<Month> Month { get; set; }
   public IEnumerable<Category> Category { get; set; }
   public IEnumerable<Expenses> Expenses { get; set; }
}

所以我有这些课程。现在,我想使用Dapper填充Expense类对象。 但是我总是将Category和PaymentModes设置为null。这是我从数据库获得的结果:

enter image description here

以下是获取费用数据的方法:

public ViewModel FetchSummaryData(Expenses expenses)
{
    DynamicParameters param = new DynamicParameters();
    ViewModel viewModel = new ViewModel();
    param.Add("@flag", expenses.flag);
    var result = db.QueryMultiple("sp_Summary", param, commandType: CommandType.StoredProcedure);
    if (result != null)
    {
        viewModel.Category = result.Read<Category>();
        viewModel.Expenses = result.Read<Expenses>();
    }

    return viewModel;
}

enter image description here

如您所见,特定ExpenseID的Category和PaymentModes始终为null。如何使用Dapper填充这些对象的属性? 谢谢。

1 个答案:

答案 0 :(得分:1)

我想您有一个Expenses表,与PaymentModes和Category表的关系为1:1。在这种情况下,您的sp应该返回Expenses表中的所有记录,并首先列出Expenses字段,然后是PaymentModes字段,最后是Category字段。像这样

QFile::symLinkTarget

如果您与PaymentModes和Category表没有任何关系,但是所有内容都存储在单个Expenses表中,则不需要联接,而只需以正确的顺序列出所有字段即可使Dapper知道如何使用您的字段填充所需的对象

select e.*, p.PaymentModeId, p.PaymentMode, c.CategoryID, c.CategoryName
from tbl_Expenses e inner join PaymentModes p on e.PaymentModeID = p.PaymentModeID
               inner join Category c on e.CategoryID = c.CategoryID
where ......

无论如何,您使用

select ExpenseID, Price, ExpenseDate, ....., 
       PaymentModeID, PaymentMode,
       CategoryID, CategoryName
from tbl_Expenses
where ....

此时,结果变量为var result = db.Query<Expenses, PaymentModes, Category, Expenses>("sp_Summary", (e,p,c) => { e.PaymentModes = p; e.Category = c; return e; }, splitOn: "PaymentModeID,CategoryID", param: param, commandType: CommandType.StoredProcedure); ,并设置了正确的 PaymentModes Category

splitOn 参数允许Dapper知道应该在哪个字段上将结果数据分隔为Query方法调用所要求的三个对象。

因此,将直到PaymentModeID的所有字段都分配给Expenses变量,然后将直到CategoryID的字段都分配到PaymentModes变量,并将最后一个字段的类别字段传递给lambda表达式。
在lambda内部,您只需将 p c 变量分配给Expenses变量的适当字段,并满足Func签名返回Expenses变量