Dapper - API đa ánh xạ đảm bảo bạn đặt splitOn

Aug 27 2020

Đối với mã hiển thị bên dưới, tôi nhận được thông báo lỗi sau.

*** Lỗi ***

Khi sử dụng các API đa ánh xạ, hãy đảm bảo bạn đặt tham số splitOn nếu bạn có các khóa khác với Id (Tham số 'splitOn')

Từ những gì tôi hiểu, tôi đang truyền tham số splitOn, tôi có thiếu điều gì rõ ràng không?


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


Cập nhật

Mã Proc được lưu trữ


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


Trả lời

2 Steve Aug 27 2020 at 04:48

Tôi không có dữ liệu của bạn, nhưng tôi nghĩ bạn nên thay đổi mã của mình theo cách này

// 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 sẽ không xây dựng và truyền trực tiếp danh sách LookUpValue, nhưng nó sẽ lặp qua các bản ghi tạo các đối tượng từ mỗi bản ghi trả về và chuyển từng đối tượng này sang biểu thức lambda.
Biểu thức lambda của bạn có thể sử dụng Từ điển để lưu trữ từng đối tượng LookupTable nhận được và thêm đối tượng LookupValue vào thuộc tính của nó. Khi Dapper kết thúc quá trình lặp lại bản ghi, các đối tượng của bạn được lưu trữ trong bộ sưu tập Giá trị của từ điển

Tất nhiên, điều này giả định rằng lớp LookUpTable của bạn có thuộc List<LookUpValue>tính

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

Lưu ý cách thuộc tính tạo danh sách lúc khởi tạo để tránh logic phức tạp trong biểu thức lambda Dapper.