尝试在 Dapper 中映射实体时出错(多映射错误:splitOn 列)

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

错误: System.ArgumentException:多映射错误:未找到 splitOn 列“Id” - 请确保您的 splitOn 参数已设置且顺序正确(参数“splitOn”)。

当我在管理员角色上使用检查 IdentityRoles 时会发生这种情况。如果您删除所有检查和所有与此相关的逻辑,那么一切都会开始工作。请参阅下面的示例。

GetTransportationRequestQueryHandler代码:

internal sealed class GetTransportationRequestQueryHandler
    : IQueryHandler<GetTransportationRequestQuery, IReadOnlyList<GetTransportationRequestResponse>>
{
    private readonly ISqlConnectionFactory _sqlConnectionFactory;

    public GetTransportationRequestQueryHandler(ISqlConnectionFactory sqlConnectionFactory)
    {
        _sqlConnectionFactory = sqlConnectionFactory;
    }

    public async Task<Result<IReadOnlyList<GetTransportationRequestResponse>>> Handle(
        GetTransportationRequestQuery request, CancellationToken cancellationToken)
    {
        string sqlString =
               """
               SELECT
                   a.id AS Id,
                   a.created_by AS CreatedBy, 
                   a.created_on_utc AS CreatedOnUtc,
                   a.last_modified_date_on_utc AS LastModifiedDateOnUtc,
                   a.last_modified_by AS LastModifiedBy,
                   a.type_of_request AS TypeOfRequest,
                   a.customs_clearance AS CustomsClearance,
                   a.delivery_conditions AS DeliveryConditions,
                   a.cargo_readiness_period AS CargoReadinessPeriod,
                   a.deadline_for_submitting_commercial_offer AS DeadlineForSubmittingCommercialOffer,
                   a.type_of_cargo AS TypeOfCargo,
                   a.type_of_packaging AS TypeOfPackaging,
                   a.container_type AS ContainerType,
                   a.places_in_container AS PlacesInContainer,
                   a.loading_in_one_container_net AS LoadingInOneContainerNeT,
                   a.number_of_containers AS NumberOfContainers,
                   a.weight_of_one_place AS WeightOfOnePlace,
                   a.loading_per_container_gross_ton AS LoadingPerContainerGrossTon,  
                   a.port_of_shipment AS PortOfShipment,
                   a.transshipment_port AS TransshipmentPort,
                   a.place_of_delivery AS PlaceOfDelivery,
                   a.cargo_pickup_address AS CargoPickupAddress,
                   a.note AS Note,
                   a.is_visible AS IsVisible,
                   a.index AS Index
               FROM transportation_request AS a
               """;

        if (!request.IdentityUser.IdentityRoles.Contains("Administrator"))
        {
            var firstIndexOfWord = IndexOfFirstLetter(sqlString, "a.created_by");
            var lastIndexOfWord = IndexOfLastLetter(sqlString, "LastModifiedBy,\r\n    ");
            sqlString = sqlString.Remove(firstIndexOfWord, lastIndexOfWord - firstIndexOfWord);
        }

        using var connection = _sqlConnectionFactory.CreateConnection();

        var transportationRequestResponse = await connection.QueryAsync<GetTransportationRequestResponse>(
            sqlString,
            new[]
            {
                typeof(Guid),
                request.IdentityUser.IdentityRoles.Contains("Administrator") ? null : typeof(Audit),
                typeof(TypeOfRequest),
                typeof(LogisticsProcess),
                typeof(CargoCharacteristics),
                typeof(CharacteristicsOfTheContainer),
                typeof(LogisticsHubs),
                typeof(string),
                typeof(bool),
            },
            objects =>
            {
                Guid id = (Guid)objects[0];
                Audit? audit = (Audit)objects[1];
                TypeOfRequest typeOfRequest = (TypeOfRequest)objects[2];
                LogisticsProcess logisticsProcess = (LogisticsProcess)objects[3];
                CargoCharacteristics cargoCharacteristics = (CargoCharacteristics)objects[4];
                CharacteristicsOfTheContainer characteristicsOfTheContainer = (CharacteristicsOfTheContainer)objects[5];
                LogisticsHubs logisticsHubs = (LogisticsHubs)objects[6];
                string note = (string)objects[7];
                bool isVisible = (bool)objects[8];

                GetTransportationRequestResponse getTransportationRequestResponse = new(
                id,
                audit,
                typeOfRequest,
                logisticsProcess,
                cargoCharacteristics,
                characteristicsOfTheContainer,
                logisticsHubs,
                note,
                isVisible);

                return getTransportationRequestResponse;
            },
            splitOn: $"Id{(request.IdentityUser.IdentityRoles.Contains("Administrator") ? ",CreatedBy," : ",")}TypeOfRequest,CustomsClearance,TypeOfCargo,ContainerType,PortOfShipment,Note,IsVisible");         
           

        return transportationRequestResponse.ToList();
    }`

IndexOfFirstLetter方法代码:

int IndexOfFirstLetter(string str, string word)
{
    var stringCharArray = str.ToCharArray();
    var wordCharArray = word.ToCharArray();

    int wordLength = wordCharArray.Length;
    int wordIndex = 0;
    int coincidenceCounter = 0;
    int tmpValueForWordIndex = 0;
    int counterForWhile = 0;

    for (int i = 0; i < stringCharArray.Length; i++)
    {
        while (counterForWhile < wordLength)
        {
            if (stringCharArray[i] == wordCharArray[counterForWhile])
            {
                tmpValueForWordIndex = i;
                ++coincidenceCounter;
                counterForWhile++;

                if (coincidenceCounter == wordLength)
                {
                    wordIndex = tmpValueForWordIndex - (wordLength - 1);
                }
                break;
            }
            if (stringCharArray[i] != wordCharArray[counterForWhile])
            {
                coincidenceCounter = 0;
                counterForWhile = 0;
                break;
            }
        }
    }

    return wordIndex;
}

IndexOfLastLetter方法代码:

int IndexOfLastLetter(string str, string word)
{
    var stringCharArray = str.ToCharArray();
    var wordCharArray = word.ToCharArray();

    int wordLength = wordCharArray.Length;
    int wordIndex = 0;
    int coincidenceCounter = 0;
    int tmpValueForWordIndex = 0;
    int counterForWhile = 0;

    for (int i = 0; i < stringCharArray.Length; i++)
    {
        while (counterForWhile < wordLength)
        {
            if (stringCharArray[i] == wordCharArray[counterForWhile])
            {
                tmpValueForWordIndex = i;
                ++coincidenceCounter;
                counterForWhile++;

                if (coincidenceCounter == wordLength)
                {
                    wordIndex = tmpValueForWordIndex;
                }

                break;
            }
            if (stringCharArray[i] != wordCharArray[counterForWhile])
            {
                coincidenceCounter = 0;
                counterForWhile = 0;
                break;
            }
        }
    }

    return wordIndex;
}

如果没有管理员角色,这段代码会删除部分sql行。

if (!request.IdentityUser.IdentityRoles.Contains("Administrator"))
{
    var firstIndexOfWord = IndexOfFirstLetter(sqlString, "a.created_by");
    var lastIndexOfWord = IndexOfLastLetter(sqlString, "LastModifiedBy,\r\n    ");
    sqlString = sqlString.Remove(firstIndexOfWord, lastIndexOfWord - firstIndexOfWord);
}

删除sql行后如下所示:

SELECT
    a.id AS Id,
    a.type_of_request AS TypeOfRequest,
    a.customs_clearance AS CustomsClearance,
    a.delivery_conditions AS DeliveryConditions,
    a.cargo_readiness_period AS CargoReadinessPeriod,
    a.deadline_for_submitting_commercial_offer AS DeadlineForSubmittingCommercialOffer,
    a.type_of_cargo AS TypeOfCargo,
    a.type_of_packaging AS TypeOfPackaging,
    a.container_type AS ContainerType,
    a.places_in_container AS PlacesInContainer,
    a.loading_in_one_container_net AS LoadingInOneContainerNeT,
    a.number_of_containers AS NumberOfContainers,
    a.weight_of_one_place AS WeightOfOnePlace,
    a.loading_per_container_gross_ton AS LoadingPerContainerGrossTon,  
    a.port_of_shipment AS PortOfShipment,
    a.transshipment_port AS TransshipmentPort,
    a.place_of_delivery AS PlaceOfDelivery,
    a.cargo_pickup_address AS CargoPickupAddress,
    a.note AS Note,
    a.is_visible AS IsVisible,
    a.index AS Index
FROM transportation_request AS a

这个sql查询是正确的: 在此输入图片描述 正如我已经说过的,如果您删除检查管理员角色的逻辑,那么一切都会正常。 然后我得到这样的回应: 在此输入图片描述

请帮助我理解我做错了什么

我查看了有关此问题的许多主题,但没有找到答案。

c# asp.net-core dapper npgsql .net-8.0
1个回答
0
投票

SplitOn
是将单行数据拆分为多个对象。例外说得很好。

您出现异常的原因是您发布的sql查询中没有列

CreatedBy
并标记为
correct

此外,这与为什么如果您使用

Administrator
删除逻辑它效果很好,因为 - 那么您的
CreatedBy
中没有
splitOn
列。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.