如何使用dapper将多个与多个关系映射到列表

时间:2016-05-04 08:11:02

标签: c# oracle dapper

我有一个类AnalysisRule

public class AnalysisRule
{
    public long Id { get; set; }
    public Analysis Analysis { get; set; }
    public AnalysisCategory AnalysisCategory { get; set; }
    public Gender Gender { get; set; }
    public bool FatherHerdBookRequired { get; set; }
    public bool MotherHerdBookRequired { get; set; }
    public List<Breed> AllowedBreeds { get; set; }
}

有一个品种列表

public class Breed
{
    public long BreedId { get; set; }
    public long AnimalTypeId { get; set; }
    public long BreedCode { get; set; }
    public string BreedName { get; set; }
    public string BreedAcronym { get; set; }
}

这是我与DB表绑定在一起的多对多关系 AnalysisRulesBreeds enter image description here

品种

enter image description here

和AnalysisRules enter image description here

用Dapper我试过

    var sql = @"select *
                from ""AnalysisRules"" 
                join ""AnalysisCategory"" on ""AnalysisRules"".""AnalysisCategoryId"" = ""AnalysisCategory"".""Id""  
                join ""Analysis"" on ""AnalysisRules"".""AnalysisId"" = ""Analysis"".""Id""
                left join ""AnalysisRulesBreeds"" on ""AnalysisRulesBreeds"".""AnalysisRuleId"" = ""AnalysisRules"".""Id""
                left join ""Breed"" on ""AnalysisRulesBreeds"".""BreedId"" = ""Breed"".""BreedId""
                where ""AnalysisId"" = :AnalysisId";
    rules = sqlConnection.QueryAsync<AnalysisRule, AnalysisCategory, Analysis, Breed, AnalysisRule>(
        sql,
        (ar, c, a, b) =>
        {
            ar.AnalysisCategory = c;
            ar.Analysis = a;
            ar.Breeds.Add(b);
            return ar;
        },
        new
        {
            AnalysisId = analysisId
        },
        splitOn:"BreedId");

哪个给了我

  

'当使用多映射API时,如果您的ID不是Id,请确保设置splitOn参数   参数名称:splitOn

如果我在SQL Developer中运行相同的查询,我会得到2行具有相同的Id但在Breed中具有不同的数据,因此查询应该足够好。

那么我该如何将这2行放入一个AnalysisRule实体中,其中Breeds由2个Breed实体组成?

修改 我现在有

                    sqlConnection.Open();

                var sql = @"select  ar.*,
                                    ac.*,
                                    b.*                 

                            from ""AnalysisRules"" ar
                            join ""AnalysisCategory"" ac on ar.""AnalysisCategoryId"" = ac.""Id""  
                            join ""Analysis"" a on ar.""AnalysisId"" = a.""Id""

                            left join ""AnalysisRulesBreeds""  on ""AnalysisRulesBreeds"".""AnalysisRuleId"" = ar.""Id""
                            left join ""Breed"" b  on ""AnalysisRulesBreeds"".""BreedId"" = b.""Id""

                            where ""AnalysisId"" = :AnalysisId";

                var rules = sqlConnection.QueryAsync<AnalysisRule, AnalysisCategory, Analysis, Breed, AnalysisRule>(
                    sql,
                    (ar, c, a, b) =>
                    {
                        ar.AnalysisCategory = c;
                        ar.Analysis = a;
                        ar.Breeds.Add(b);
                        return ar;
                    },
                    new
                    {
                        AnalysisId = analysisId
                    });

                return await rules;

删除了splitOn,将AnalysisRulesBreedsId更改为Id,但我仍然得到

  

使用多映射API时,如果您的ID不是Id,请确保设置splitOn参数   参数名称:splitOn

如果我在SQLDev中执行相同的查询,我会得到 enter image description here

1 个答案:

答案 0 :(得分:1)

通过选择*,您将获得每个联接表的列。您还要将splitOn设置为BreedId。现在,Dapper希望将一个连接表的行列与下一个连接表分开,它应该查找名为BreedId的列。

这不起作用,因为除AnalysisRulesBreeds之外的所有表都使用Id作为id列名。

尝试删除splitOn参数,然后默认为Id。然后调整select-clause以仅从结果中实际需要的表中进行选择,例如

select AnalysisRule.*, AnalysisCategory.*, Analysis.*, Breed.*

(假设您的Analysis表和AnalysisCategory表遵循具有名为'Id'的Id列的约定。)