当要映射的对象共享类型时,无法使用 Dapper Multimap(SQL 限制具有唯一的列名称)

问题描述 投票:0回答:1

我正在尝试将我的简洁查询绑定到我已经布置的一些模型。我的 4 个对象使用

User
模型作为带有字段
INTERNAL_USER_NUMBER
FIRST_NAME
LAST_NAME
等的类型。但是在 SQL Server 中,您不能使用相同的列进行查询。

因此,在我的 Dapper multimap 函数中,我无法拆分

INTERNAL_USER_NUMBER
4 次来绑定我的数据。不知道如何解决这个问题:

var certificationReviews2 = await connection.QueryAsync<ARMS_API.Models.CertificationReview>("select * from dbo.A2F_DMCP_0005_BrowseTest()", 
types: new[] { 
    typeof(ARMS_API.Models.CertificationReview), 
    typeof(State), 
    typeof(ARMS_API.Models.Program), 
    typeof(ActuarialFirm), 
    typeof(User), 
    typeof(User), 
    typeof(User) , 
    typeof(User)
    },
map: (objects) => {
    var certificationReview = (ARMS_API.Models.CertificationReview)objects[0];
    certificationReview.STATE = (State)objects[1];
    certificationReview.STATE.PROGRAMS.Add((ARMS_API.Models.Program)objects[2]);
    certificationReview.ACTUARIAL_FIRM = (ActuarialFirm)objects[3];
    certificationReview.ACTUARIAL_FIRM.CERTIFYING_ACTUARY.Add((User)objects[4]);
    certificationReview.PRIMARY_REVIEWER = (User)objects[5];
    certificationReview.SECONDARY_REVIEWER = (User)objects[6];
    certificationReview.DMCP_ANALYST = (User)objects[7];

    return certificationReview;
},
splitOn: "STATE_ID,PROGRAM_DD,ACTUARIAL_FIRM_DD,INTERNAL_USER_NUMBER,INTERNAL_USER_NUMBER,INTERNAL_USER_NUMBER,INTERNAL_USER_NUMBER");
c# sql-server asp.net-core dapper
1个回答
0
投票

在尝试将 SQL Server 查询中的数据绑定到模型时,您遇到了 Dapper 的

QueryAsync
方法的问题。您的查询涉及
User
模型的多个实例,SQL Server 不允许查询返回具有相同名称的多个列,因此您不能对不同的
 多次使用相同的 
splitOn
 参数(例如,
INTERNAL_USER_NUMBER
User
物体。

要解决此问题,您可以使用 SQL 列别名来确保相似数据的每个实例(例如,每个

User
模型的
INTERNAL_USER_NUMBER
FIRST_NAME
LAST_NAME
等)在结果集中具有唯一的名称。这涉及更改 SQL 查询,以便与不同
User
对象相关的每个字段都具有不同的别名。例如,在列名称前面或后面添加一些指示其角色或位置的内容(例如,
CertifyingActuary_INTERNAL_USER_NUMBER
PrimaryReviewer_INTERNAL_USER_NUMBER
等)。在 Dapper
QueryAsync
调用中,使用
splitOn
参数来指定唯一的要映射到不同对象的每组数据的第一列的别名。这会告诉 Dapper 在哪里分割数据以映射到模型。
splitOn
参数应与来自修改后的 SQL 查询的每个对象集的第一个别名列名称匹配。

sql查询:

SELECT 
    cr.*, -- this fetches CertificationReview fields
    s.STATE_ID, s.OtherStateFields, -- State fields with aliases if needed
    p.PROGRAM_DD, p.OtherProgramFields, -- Program fields with aliases if needed
    af.ACTUARIAL_FIRM_DD, af.OtherActuarialFirmFields, -- ActuarialFirm fields
    ca.INTERNAL_USER_NUMBER as CertifyingActuary_USER_NUMBER, ca.FIRST_NAME as CertifyingActuary_FIRST_NAME, -- etc
    pr.INTERNAL_USER_NUMBER as PrimaryReviewer_USER_NUMBER, pr.FIRST_NAME as PrimaryReviewer_FIRST_NAME, -- etc
    sr.INTERNAL_USER_NUMBER as SecondaryReviewer_USER_NUMBER, sr.FIRST_NAME as SecondaryReviewer_FIRST_NAME, -- etc
    da.INTERNAL_USER_NUMBER as DmcpAnalyst_USER_NUMBER, da.FIRST_NAME as DmcpAnalyst_FIRST_NAME -- etc
FROM dbo.A2F_DMCP_0005_BrowseTest() -- Assuming this is your complex query or view

对于

splitOn
参数,您现在指定要分割的每个对象的第一个别名列。只需确保这些名称与您在 SQL 查询中为其指定的别名完全匹配即可。

var certificationReviews2 = await connection.QueryAsync<ARMS_API.Models.CertificationReview, State, ARMS_API.Models.Program, ActuarialFirm, User, User, User, User, ARMS_API.Models.CertificationReview>(
    "your_modified_sql_here", // your updated SQL query string here
    (certificationReview, state, program, actuarialFirm, certifyingActuary, primaryReviewer, secondaryReviewer, dmcpAnalyst) => {
        certificationReview.STATE = state;
        certificationReview.STATE.PROGRAMS.Add(program);
        certificationReview.ACTUARIAL_FIRM = actuarialFirm;
        certificationReview.ACTUARIAL_FIRM.CERTIFYING_ACTUARY.Add(certifyingActuary);
        certificationReview.PRIMARY_REVIEWER = primaryReviewer;
        certificationReview.SECONDARY_REVIEWER = secondaryReviewer;
        certificationReview.DMCP_ANALYST = dmcpAnalyst;

        return certificationReview;
    },
    splitOn: "STATE_ID,PROGRAM_DD,ACTUARIAL_FIRM_DD,CertifyingActuary_USER_NUMBER,PrimaryReviewer_USER_NUMBER,SecondaryReviewer_USER_NUMBER,DmcpAnalyst_USER_NUMBER"
).ConfigureAwait(false);
© www.soinside.com 2019 - 2024. All rights reserved.