Reputation: 1459
I did some digging into this, but I don't quite understand it. I have a Microsoft.Extensions.Logging.EventId on an object and I've used Dapper to preserve the EventId in my database. I used two columns: EventId (int) and EventName (varchar(…)). However, I can't quite figure out how to populate the one property object (EventId) from the two database columns.
I tried manipulating my SQL . .
SELECT <snip>…[EventId] AS [EventId.Id],[EventName] AS [EventId.Name] . . .
but that worked about as you might expect.
So, here's my xunit test:
[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);
}
which proves that this function doesn't work:
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>();
}
You can see that I attempted to use the map function sort of like this person did: https://taylorhutchison.github.io/2016/03/23/dapper-orm-complex-queries.html, but the Name always turns up NULL, regardless of my approach.
Anyone see where I'm going wrong?
If relevant, here is my 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]";
Help is always appreciated.
V
Upvotes: 2
Views: 382
Reputation: 2320
EventName will not map to Event.Name
Change your SQL to
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]";
and your spliton: "Id"
Upvotes: 1