Dapper - Multi-Mapping-APIs stellen sicher, dass Sie splitOn festlegen

Aug 27 2020

Für den unten gezeigten Code wird die folgende Fehlermeldung angezeigt.

*** Error ***

Stellen Sie bei Verwendung der Multi-Mapping-APIs sicher, dass Sie den Parameter splitOn festlegen, wenn Sie andere Schlüssel als Id haben (Parameter 'splitOn').

Soweit ich weiß, übergebe ich den splitOn-Parameter. Fehlt mir etwas Offensichtliches?

Code


 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();
                }


Aktualisieren

Gespeicherter Proc-Code


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


Antworten

2 Steve Aug 27 2020 at 04:48

Ich habe Ihre Daten nicht, aber ich denke, Sie sollten Ihren Code auf diese Weise ändern

// 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 erstellt und übergibt keine Liste von LookUpValue direkt, sondern durchläuft die Datensätze, erstellt die Objekte aus jedem zurückgegebenen Datensatz und übergibt diese Objekte einzeln an den Lambda-Ausdruck.
Ihr Lambda-Ausdruck könnte ein Wörterbuch verwenden, um jedes empfangene LookupTable-Objekt zu speichern und das LookupValue-Objekt zu seiner Eigenschaft hinzuzufügen. Wenn Dapper seine Iteration über den Datensatz beendet, werden Ihre Objekte in der Values-Auflistung des Wörterbuchs gespeichert

Dies setzt natürlich voraus, dass Ihre Klasse LookUpTable eine List<LookUpValue>Eigenschaft hat

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

Beachten Sie, wie die Eigenschaft die Liste bei der Initialisierung erstellt, um komplexe Logik im Dapper-Lambda-Ausdruck zu vermeiden.