【问题标题】:Dapper Multi-mapping IssueDapper 多映射问题
【发布时间】:2012-10-11 01:51:08
【问题描述】:

以下代码块继续遇到“使用多映射 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();

【问题讨论】:

  • 你的解决方法很好......你的桌子上有什么主键?
  • 山姆,感谢您的回复。以下是键:Account:AccountId 作为 PK,BranchId 和 ApplicationId 作为 FK 分支:BranchId 作为 PK 应用程序:ApplicationId 作为 PK
  • 另一个注意事项:如果我删除应用程序,它会起作用。

标签: dapper


【解决方案1】:

在调试 Dapper 的源代码几个小时后,我终于找到了问题所在,而且很有趣。

当提供多个 splitOn 字段时,Dapper 会根据逗号进行拆分,例如var splits = splitOn.Split(',').ToArray().然后它遍历所有记录集字段并根据上述数组将它们拆分为对象;非常困难。

现在有趣的部分是:当我提供 splitOn 字段时,逗号后有一个额外的空格,例如“AccountId,BranchId”和那个小空间是原因。在 Split() 之后,BranchId 字段包含一个额外的空格,并且无法与记录集中的任何字段匹配。

有两种解决方法:

  1. 不要在逗号后使用多余的空格;我个人上瘾的 至; SQL 的一个旧习惯。
  2. 修改 Dapper 的 GenerateDeserializers 方法和更改: var currentSplit = splits[splitIndex] to 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多