Dapper - API đa ánh xạ đảm bảo bạn đặt splitOn
Đố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?
Mã
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
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.