在使用子对象列表读取对象时,需要无参数的默认构造函数来允许dapper实现错误

Rog*_*ger 1 c# asp.net-mvc-3 dapper

我有这个:

public class object_a
{
    public int ta_Id { get; set; }
    public string ta_Label { get; set; }
    public IEnumerable<table_c> SomeName { get; set; }
}

public class table_b
{
    public int Id {get;set;}
    public int SomeId {get;set;}
    public int FK_A {get;set;}
}

public class table_c
{
    public int Id {get;set;}
    public int Max {get;set;}
    public string Label {get;set;}
    public int FK_A {get;set;}
}
Run Code Online (Sandbox Code Playgroud)

使用Dapper我检索object_a包含任意数量子对象的列表table_c

using (System.Data.SqlClient.SqlConnection sqlConnection = new System.Data.SqlClient.SqlConnection(_con))
{
        sqlConnection.Open();
        var sql = string.Format(
        @"
        select ta.Id as ta_Id, ta.Label as ta_label, splitLimit = '', tc.Id, tc.Max, tc.Label
        from table_a as ta
        left join table_b as tb
        on tb.FK_A = ta.Id
        left join table_c as tc
        on tc.FK_A = ta.Id
        where tb.SomeId = SomeInt);

        var items = sqlConnection.Query<object_a, IEnumerable<table_c>, object_a>(sql, (a, c) => { a.c = table_c; return a; }, splitOn: "splitLimit");
        return items;
    }
Run Code Online (Sandbox Code Playgroud)

从控制器调用Dapper代码时,我收到此错误:

需要无参数的默认构造函数来实现精确的实现

我也试过这个:

var items = sqlConnection.Query<object_a,IEnumerable<table_c>, object_a>(sql, (a, c) => 
{ 
                    if (c!= null) 
                    {
                        a.SomeName = c;
                    } 
                    return a; 

                }, splitOn: "splitLimit");
Run Code Online (Sandbox Code Playgroud)

我认为它可能与此有关IEnumerable<table_c>但我不明白我在这里做错了什么.我已经阅读了相关的问题,但是我没有"得到"它.

我想知道我做错了什么以及正确的代码是什么.谢谢!

Mar*_*ell 6

问题是IEnumerable<>,这里:

Query<object_a, IEnumerable<table_c>, object_a>
Run Code Online (Sandbox Code Playgroud)

小巧玲珑无法创造IEnumerable<table_c>,而且永远不会.此方法的工作方式是:

Query<object_a, table_c, object_a>
Run Code Online (Sandbox Code Playgroud)

然后对于每一行,dapper将从行创建一个object_a和一个table_c,然后使用用户提供的方法将两者结合起来.目前,我们没有任何内置代码来执行基于身份的聚合,但可以在自定义方法中添加 - 例如,以下尝试汇总重复object_a实例:

var identityMap = new Dictionary<int, object_a>();
var data = Query<object_a, table_c, object_a>(sql, (a, c) => {
    object_a master;
    if(!identityMap.TryGetValue(a.ta_id, out master)) {
        identityMap[a.ta_id] = master = a;
    }
    var list = (List<table_c>)master.SomeName;
    if(list == null) {
        master.SomeName = list = new List<table_c>();
    }
    list.Add(c);
    return master;
}, ...).Distinct().ToList();
Run Code Online (Sandbox Code Playgroud)