与Dapper连接返回null

时间:2018-01-03 13:50:30

标签: c# sql dapper

我有以下课程:

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Department { get; set; }
    public List<Event> Events { get; set; }
}

public class Event
{
    public int Id { get; set; }
    public int UserId { get; set; }
    public string EventText { get; set; }
    public string StartTime { get; set; }
    public string EndTime { get; set; }
    public string Day { get; set; }
    public string ColorIdentifier { get; set; }
    public int Week { get; set; }
}

我试图通过Dapper获取所有用户及其活动:

var sql = "SELECT u.Id, e.UserId, e.EventText FROM cpc.PLANNING_TOOL_USERS u  LEFT JOIN cpc.PLANNING_TOOL_EVENTS e ON u.Id=e.UserId";
var result = SqlMapper.Query<User, Event, User>(connection, sql, (u, e) =>
{
   if (u.Events == null)
      u.Events = new List<Event>();
   u.Events.Add(e);

   return u;

}, splitOn: "Id, UserId");

返回用户的Id,但不填充事件列表。我已经在Stack Overflow上看到了很多这方面的例子,但是我无法看到我做错了什么。

1 个答案:

答案 0 :(得分:1)

要省略SQL没有返回数据的情况,我刚刚使用SQL union模拟了两个用户行。 User Id=1EventUser Id=2Event

SqlMapper.Query会返回最适合1比1关系的平坦结果。您有一个用户与多个事件关系,因此需要一些帮助程序存储来维护该关系作为映射到结果。我已经使用了.NET字典。

我的代码示例如下:

        // introducing temporary storage
        var usersDictionary = new Dictionary<int, User>();

        var sql = @"SELECT 1 Id, 1 UserId, 'EventText1' EventText
                  union SELECT 2 Id, 2 UserId, 'EventText2'  EventText
                  union SELECT 2 Id, 2 UserId, 'Another EventText2' EventText";
        var result = SqlMapper.Query<User, Event, User>(connection, sql, (u, e) =>
        {
            if (!usersDictionary.ContainsKey(u.Id))
                usersDictionary.Add(u.Id, u);
            var cachedUser = usersDictionary[u.Id];

            if (cachedUser.Events == null)
                cachedUser.Events = new List<Event>();
            cachedUser.Events.Add(e);

            return cachedUser;

        }, splitOn: "UserId");

        // we are not really interested in `result` here
        // we are more interested in the `usersDictionary`

        var users = usersDictionary.Values.AsList();
        Assert.AreEqual(2, users.Count);
        Assert.AreEqual(1, users[0].Id);
        CollectionAssert.IsNotEmpty(users[0].Events);
        Assert.AreEqual(1, users[0].Events.Count);
        Assert.AreEqual("EventText1", users[0].Events[0].EventText);
        Assert.AreEqual(2, users[1].Events.Count);

我希望这有助于您解决映射问题和事件null