继续遇到以下代码块的“使用多重映射API时,如果您具有ID以外的键,请确保设置splitOn参数”错误:
var accounts = DbConnection.Query<Account, Branch, Application, Account>(
"select Accounts.*, SplitAccount = '', Branches.*, SplitBranch = '', Applications.*" +
" from Accounts" +
" join Branches" +
" on Accounts.BranchId = Branches.BranchId" +
" join Applications" +
" on Accounts.ApplicationId = Applications.ApplicationId" +
" where Accounts.AccountId <> 0",
(account, branch, application) =>
{
account.Branch = branch;
account.Application = application;
return account;
}, splitOn : "SplitAccount, SplitBranch"
).AsQueryable();
我正在使用SplitAccount和SplitBranch作为splitOn的解决方法。
我错过了什么吗?
谢谢
编辑:
我已经整理了一下测试,下面是一个简单的类和一个新的查询:
public class AccountLight
{
public int AccountId { get; set; }
public string AccountNumber { get; set; }
public BranchLight Branch { get; set; }
public ApplicationLight Application { get; set; }
}
public class BranchLight
{
public int BranchId { get; set; }
public string BranchNumber { get; set; }
}
public class ApplicationLight
{
public int ApplicationId { get; set; }
public string ApplicationCode { get; set; }
}
var accounts2 = DbConnection.Query<AccountLight, BranchLight, ApplicationLight, AccountLight>(
"select Accounts.AccountId, Accounts.AccountNumber," +
" Branches.BranchId, Branches.BranchNumber," +
" Applications.ApplicationId, Applications.ApplicationCode" +
" from Accounts" +
" inner join Branches" +
" on Accounts.BranchId = Branches.BranchId" +
" inner join Applications" +
" on Accounts.ApplicationId = Applications.ApplicationId" +
" where Accounts.AccountId <> 0",
(account, brach, application) =>
{
account.Branch = brach;
account.Application = application;
return account;
},
commandType: CommandType.Text,
splitOn: "AccountId, BranchId"
).AsQueryable();
最佳答案
在调试了Dapper的源代码几个小时之后,我终于找到了这个问题,这很有趣。
提供多个splitOn字段时,Dapper会基于逗号进行拆分,例如var splits = splitOn.Split(',')。ToArray()。然后,它将遍历所有记录集字段,并根据上述数组将其拆分为对象;海峡前进。
现在最有趣的部分是:当我提供splitOn字段时,在逗号后有一个额外的空格,例如原因是“AccountId,BranchId”,这是很小的空间。在Split()之后,BranchId字段包含多余的空间,无法与记录集中的ANY字段匹配。
有两种解决方法:
至; SQL的一个旧习惯。
方法和更改:var currentSplit =将[splitIndex]拆分为var
currentSplit = splits [splitIndex] .Trim()或类似的东西;这就是我为本地副本所做的。
这是代码快照:
private static Func<IDataReader, object>[] GenerateDeserializers(Type[] types, string splitOn, IDataReader reader)
{
int current = 0;
var splits = splitOn.Split(',').ToArray();
var splitIndex = 0;
Func<Type, int> nextSplit = type =>
{
var currentSplit = splits[splitIndex].Trim();
if (splits.Length > splitIndex + 1)
{
splitIndex++;
}
更新:
上面的修复程序已合并:https://github.com/SamSaffron/dapper-dot-net/commit/399db17e5aa6f1eefaf8fdccff827020be8e6cbb