我在使用Dapper.net执行查询时遇到问题。 在下面的代码示例中,您可以看到一些子选择,我将其别名添加到我想要的列名称,并且它也与我的对象的属性名称完全对应。
但是,在结果中,没有正确填写与子查询对应的属性(始终为0)。
我也查询了查询,如果我执行我在sql profiler中看到的查询,结果是正确的(例如,例如NrEvents确实有一个值,就像在我生成的对象中一样,它总是0 )。
此外,TvLogLockInfo与EMUser的映射是正确的,可以很好地转换,因此没有问题。
编辑:实际上..如果删除EMUser的映射,子查询值DO将被填写。 所以问题是,如何在TvLogLockInfo和EMUser之间添加映射并保持子查询值的填充..?
// this query will give me the correct values, but I lose the mapping of EMUser
res = ctx.Connection.Query<TvLogLockInfo>(query + where, qParams).ToList();
这是完整的搜索功能:
public List<TvLogLockInfo> SearchTvLogs(DateTime? dateFrom, DateTime? dateUntil, List<int> stationIds, bool isLockedOnly)
{
List<TvLogLockInfo> res;
const string query = " SELECT /* tv log */ " +
" L.TvLogId, L.ReferenceDay, L.StationId, L.IsLocked, l.LockedDate, l.LockedByUserId, " +
" /* all events */ " +
" (SELECT COUNT(TvLogEventId) FROM TvLogEvent E WITH (NOLOCK) WHERE E.TvLogId = L.TvLogId) AS NrEvents, " +
" (SELECT COUNT(TvLogEventId) FROM TvLogEvent E WITH (NOLOCK) WHERE E.TvLogId = L.TvLogId AND E.IsTimeSet = 1) AS NrEventsTimeSet, " +
" /* spots */ " +
" (SELECT COUNT(TvLogEventId) FROM TvLogEvent E WITH (NOLOCK) WHERE E.TvLogId = L.TvLogId AND E.ThesaurusTypeEMListValueId = @spot AND E.MatchingInfoId IS NULL) AS NrSpotsNotMatched, " +
" (SELECT COUNT(TvLogEventId) FROM TvLogEvent E WITH (NOLOCK) " +
" INNER JOIN MatchingInfo I WITH (NOLOCK) ON E.MatchingInfoId = I.MatchingInfoId AND I.MatchStatusEMListValueId = @matchNew " +
" WHERE E.TvLogId = L.TvLogId AND E.ThesaurusTypeEMListValueId = @spot) AS NrSpotsMatchedNew, " +
" (SELECT COUNT(TvLogEventId) FROM TvLogEvent E WITH (NOLOCK) " +
" INNER JOIN MatchingInfo I WITH (NOLOCK) ON E.MatchingInfoId = I.MatchingInfoId AND I.MatchStatusEMListValueId = @matchValidated " +
" WHERE E.TvLogId = L.TvLogId AND E.ThesaurusTypeEMListValueId = @spot) AS NrSpotsMatchedValidated, " +
" /* autopromo */ " +
" (SELECT COUNT(TvLogEventId) FROM TvLogEvent E WITH (NOLOCK) WHERE E.TvLogId = L.TvLogId AND E.ThesaurusTypeEMListValueId = @autopromo AND E.MatchingInfoId IS NULL) AS NrAutoPromoNotMatched, " +
" (SELECT COUNT(TvLogEventId) FROM TvLogEvent E WITH (NOLOCK) " +
" INNER JOIN MatchingInfo I WITH (NOLOCK) ON E.MatchingInfoId = I.MatchingInfoId AND I.MatchStatusEMListValueId = @matchNew " +
" WHERE E.TvLogId = L.TvLogId AND E.ThesaurusTypeEMListValueId = @autopromo) AS NrAutoPromoMatchedNew, " +
" (SELECT COUNT(TvLogEventId) FROM TvLogEvent E WITH (NOLOCK) " +
" INNER JOIN MatchingInfo I WITH (NOLOCK) ON E.MatchingInfoId = I.MatchingInfoId AND I.MatchStatusEMListValueId = @matchValidated " +
" WHERE E.TvLogId = L.TvLogId AND E.ThesaurusTypeEMListValueId = @autopromo) AS NrAutoPromoMatchedValidated, " +
" /* user */ " +
" U.* " +
" FROM TvLog L WITH (NOLOCK) " +
" LEFT JOIN EMUser U WITH (NOLOCK) ON L.LockedByUserId = U.EvoMonUserId ";
string where = string.Empty;
DynamicParameters qParams = new DynamicParameters();
qParams.AddDynamicParams(new { spot = (int)Enums.ThesaurusTypeList.Spot });
qParams.AddDynamicParams(new { autopromo = (int)Enums.ThesaurusTypeList.AutoPromotion });
qParams.AddDynamicParams(new { matchNew = (int)Enums.MatchingStatus.New });
qParams.AddDynamicParams(new { matchValidated = (int)Enums.MatchingStatus.Validated });
if (dateFrom.HasValue)
{
where += " L.ReferenceDay >= @dateFrom ";
qParams.AddDynamicParams(new { dateFrom = dateFrom });
}
if (dateUntil.HasValue)
{
where += string.Format(" {0} L.ReferenceDay <= @dateUntil ", (string.IsNullOrWhiteSpace(where) ? string.Empty : "AND"));
qParams.AddDynamicParams(new {dateUntil = dateUntil});
}
if (stationIds != null && stationIds.Count > 0)
{
where += string.Format(" {0} L.StationId IN @stationList ", (string.IsNullOrWhiteSpace(where) ? string.Empty : "AND"));
qParams.AddDynamicParams(new {stationList = stationIds});
}
if (isLockedOnly)
{
where += string.Format(" {0} L.IsLocked = 1 ", (string.IsNullOrWhiteSpace(where) ? string.Empty : "AND"));
}
if (!string.IsNullOrWhiteSpace(where)) where = " WHERE " + where;
using (var ctx = new DapperContext())
{
res = ctx.Connection.Query<TvLogLockInfo, EMUser, TvLogLockInfo>(query + where,
(tvLog, emuser) =>
{
tvLog.LockedByUser = emuser;
return tvLog;
},qParams,
splitOn: "LockedByUserId").ToList();
}
return res;
}
这是我想要结果的对象:
[Serializable]
public class TvLogLockInfo : EntityBase
{
public int TvLogId { get; set; }
public DateTime ReferenceDay { get; set; }
public int StationId { get; set; }
public bool IsLocked { get; set; }
public DateTimeOffset? LockedDate { get; set; }
public EMUser LockedByUser { get; set; }
public int NrEvents { get; set; }
public int NrEventsTimeSet { get; set; }
public int NrSpotsNotMatched { get; set; }
public int NrSpotsMatchedNew { get; set; }
public int NrSpotsMatchedValidated { get; set; }
public int NrAutoPromoNotMatched { get; set; }
public int NrAutoPromoMatchedNew { get; set; }
public int NrAutoPromoMatchedValidated { get; set; }
}
有什么想法吗?
谢谢, 汤姆
答案 0 :(得分:1)
问题可能是查询和splitOn参数的排序。您正在使用'LockedByUserId',这意味着所有列AFTER(包括)splitOn参数都属于EMUser
对象。这就是为什么EMUser的映射可以工作,但不适用于splitOn键之后的其他列。
尝试使用EvoMonUserId
作为splitOn参数。