Используйте Dapper для увлажнения сложного объекта - PullRequest
0 голосов
/ 27 августа 2018

Я немного покопался в этом, но не совсем понял. У меня есть Microsoft.Extensions.Logging.EventId для объекта, и я использовал Dapper для сохранения EventId в моей базе данных. Я использовал два столбца: EventId (int) и EventName (varchar (…)). Однако я не могу понять, как заполнить один объект свойства (EventId) из двух столбцов базы данных.

Я пытался манипулировать своим SQL. .

SELECT <snip>…[EventId] AS [EventId.Id],[EventName] AS [EventId.Name] . . .

но это сработало так, как вы могли ожидать.

Итак, вот мой тест xunit:

[Fact]
public async Task EventName_Retrievable()
{
    logger.Log(logLevel: LogLevel.Critical,
        eventId: new EventId(10, "find me"),
        exception: null,
        state: "yes please",
        formatter: (s, e) =>
        {
            return e?.Message ?? s;
        });

    var criteria = new LogQueryCriteria
    {
        MessageContains = "yes please"
    };
    var service = new LogQueryService(_fixture.ConnectionString, _factory, _performanceAgent);

    var logs = await service.FindLogsAsync(criteria);

    Assert.NotEmpty(logs);

    Assert.Equal("find me", logs.Last().EventId.Name);
}

, который доказывает, что эта функция не работает:

    public async Task<IEnumerable<ILogItemOutbound>> FindLogsAsync(LogQueryCriteria criteria)
    {
        var pe = _performanceAgent?.Start($"{nameof(LogQueryService)}.{nameof(FindLogsAsync)}", PerformanceTrackingLevel.Low);

        if (criteria == null) { criteria = new LogQueryCriteria(); }

        IEnumerable<ILogItemOutbound> results = null;
        var sql = $@"
{Constants.SELECT_LOGS}{ConstructWhereClause(criteria)} {ConstructOrderByClause(criteria)}
OFFSET {criteria.OffsetValue} ROWS FETCH NEXT {criteria.NumberPerPage} ROWS ONLY;";

        using (var connection = new SqlConnection(_connectionString))
        {
            connection.Open();
            results = await connection.QueryAsync<LogItemOutbound, EventId, LogItemOutbound>(sql: sql, commandType: System.Data.CommandType.Text,
                map: (logItem, eventId) =>
                {
                    logItem.EventId = eventId;
                    return logItem;
                }
            , splitOn: "EventId");
            _performanceAgent?.Finish(pe);
        }

        return results ?? new List<ILogItemOutbound>();
    }

Вы можете видеть, что я пытался использовать функцию карты, как это делал этот человек: https://taylorhutchison.github.io/2016/03/23/dapper-orm-complex-queries.html,, но Имя всегда имеет значение NULL, независимо от моего подхода.

Кто-нибудь видит, где я иду не так?

Если уместно, вот мой SQL:

    internal const string SELECT_LOGS = @"
SET NOCOUNT ON;
SET DEADLOCK_PRIORITY NORMAL;

SELECT [GlobalId]
,[UtcTimestamp]
,[Message]
,[LogLevel]
,[LogLevelName]
,[Source]
,[UserIdentity]
,[SessionId]
,[EventId]
,[EventName]
FROM [dbo].[Logs]";

Помощь всегда ценится.

V * +1025 *

1 Ответ

0 голосов
/ 27 августа 2018

EventName не будет сопоставлено с Event.Name

Измените ваш SQL на

 internal const string SELECT_LOGS = @"
SET NOCOUNT ON;
SET DEADLOCK_PRIORITY NORMAL;

SELECT [GlobalId]
,[UtcTimestamp]
,[Message]
,[LogLevel]
,[LogLevelName]
,[Source]
,[UserIdentity]
,[SessionId]
,[EventId] as Id
,[EventName] as Name
FROM [dbo].[Logs]";

и ваш spliton: "Id"

...