子オブジェクトのリストでオブジェクトを読み取るときに、大まかなマテリアライゼーションエラーを許容するために、パラメータを持たないデフォルトのコンストラクタが必要です

asp.net-mvc-3 c# 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;}
}

Dapperを使用して、任意の数の子オブジェクトtable_cを持つ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;
    }

コントローラから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");

IEnumerable<table_c>と何か関係があるかもしれないと思いますが、ここで間違っていることは分かりません。私はそれが示唆する関連する質問を読んだが、私はそれを "得ない"。

私は何が間違っているのか、正しいコードは何かを知りたいです。ありがとう!

受け入れられた回答

問題はIEnumerable<>です。

Query<object_a, IEnumerable<table_c>, object_a>

dapperはIEnumerable<table_c>作成することはできません。この方法の仕組みは次のとおりです。

Query<object_a, table_c, object_a>

すべての行のdapper table_cからobject_aobject_aを作成し、次にユーザー提供のメソッドを使用して2つを結合します。現在、アイデンティティベースの集約を実行するためのコードはobject_aれていませんが、カスタムメソッドで追加することができます。たとえば、次の例では、 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();


ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ