Dapper - API multi-pemetaan memastikan Anda menyetel splitOn

Aug 27 2020

Untuk kode yang ditunjukkan di bawah ini, saya mendapatkan pesan kesalahan berikut.

*** Kesalahan ***

Saat menggunakan API multi-pemetaan, pastikan Anda menyetel parameter splitOn jika Anda memiliki kunci selain Id (Parameter 'splitOn')

Dari apa yang saya mengerti saya melewati parameter splitOn apakah saya kehilangan sesuatu yang jelas?

Kode


 using (var connection = new Microsoft.Data.SqlClient.SqlConnection(connectionString))
                {
                    connection.Open();
                    LookupTables = connection.Query<LookupTable, List<LookupValue>, LookupTable>("exec [lookups].[SelAllLookupTable]", 
                        (lookuptable, lookupvalue) => {
                            lookuptable.LookUpValues = lookupvalue.ToList<LookupValue>(); 
                            return lookuptable;
                        }, splitOn: "LookupValueID").ToList();
                }


Memperbarui

Kode Proc Tersimpan


ALTER PROCEDURE [lookups].[SelAllLookupTable]
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for procedure here
    SELECT lt.[LookupTableID],
        lt.[GUID],
        lt.[CreatedBy],
        lt.[CreatedOn],
        lt.[UpdatedBy],
        lt.[UpdatedOn],
        lt.[ChangeReason],
        lt.[Name],
        lt.[Description],
        lv.[LookupValueID],
        lv.[LookupTableID],
        lv.[GUID],
        lv.[CreatedBy],
        lv.[CreatedOn],
        lv.[UpdatedBy],
        lv.[UpdatedOn],
        lv.[ChangeReason],
        lv.[Description],
        lv.[DisplayOrderNo]
    FROM lookups.LookupTable lt
    LEFT JOIN lookups.LookupValue lv ON lt.LookupTableID = lv.LookupTableID
END


Jawaban

2 Steve Aug 27 2020 at 04:48

Saya tidak memiliki data Anda, tetapi menurut saya Anda harus mengubah kode dengan cara ini

// Where we store the distinct LookUpTable found by the query
Dictionary<int, LookUpTable> result = new Dictionary<int, LookUpTable>();

using (var connection = new Microsoft.Data.SqlClient.SqlConnection(connectionString))
{
    connection.Open();
    var LookupTables = connection.Query<LookupTable, LookUpValue, LookupTable>("exec [lookups].[SelAllLookupTable]",
        (lkt, lkv) =>
        {
            // Check if we have the instance already in the dictionary
            // add it if not, 
            if (!result.ContainsKey(lkt.LookUpTableID))
               result.Add(lkt.LookUpTableID, lkt);
            result[lkt.LookupTableID].LookUpValues.Add(lkv);
            return lkt;
        }, splitOn: "LookupValueID").ToList();
}
return result.Values.ToList();

Dapper tidak akan membangun dan meneruskan daftar LookUpValue secara langsung, tetapi akan mengulangi rekaman yang membuat objek dari setiap rekaman yang dikembalikan dan meneruskan objek ini satu per satu ke ekspresi lambda.
Ekspresi lambda Anda bisa menggunakan Dictionary untuk menyimpan setiap objek LookupTable yang diterima dan menambahkan objek LookupValue ke propertinya. Saat Dapper mengakhiri iterasinya di atas rekaman, objek Anda disimpan dalam koleksi Values ​​di kamus

Tentu saja ini mengasumsikan bahwa kelas Anda LookUpTable memiliki List<LookUpValue>properti

public class LookupTable
{
    public int LookupValueID { get; set; }
    .... other properties ....
    public List<LookUpValue> LookUpValues {get;set} = new List<LookUpValue>();
}

Perhatikan bagaimana properti membuat daftar saat inisialisasi untuk menghindari logika kompleks dalam ekspresi lambda Dapper.