使用 Sql,如何从单个查询中合并子对象?

Using Sql, how can I hydrate child objects from within a single Query?

我正在使用 Dapper,但我认为这适用于一般情况 SQL:

我有以下内容:

 var dapperQuery = "select * from ( select * from [User] where " +
                                  "AccountDisabled <> 1 and " +
                                  "Rate <= @maxRate and " +
                                  "(datediff(day, Birthdate, @today) / 365) between @minage and @maxage";

 // some conditional stuff

 dapperQuery = dapperQuery + " order by LastOnline desc offset @skip rows fetch next 40 rows only ) As [Limit1] " +
                              "LEFT OUTER JOIN Photo AS [Extent2] ON [Limit1].[UserId] = [Extent2].[UserId]";

 var dbProfiles = connection.Query<User>(dapperQuery, new {
                    maxRate = query.SearchMaxRate,
                    userPoint = "POINT (" + user.LocationLong + " " + user.LocationLat + ")",
                    searchRadius = radius,
                    today = DateTime.UtcNow,
                    minAge = query.SearchLowerAge,
                    maxAge = query.SearchUpperAge,
                    skip = query.Index * 40
                }).ToList();

现在,这将返回我期望的结果,但 User.Photos 属性 始终为空。我如何从查询中对此进行补水?

我的用户 class:

[Table("User")]
public class User {

    public User() {
        Photos = new List<Photo>();
    }

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }
    public string Username { get; set; }

    public DateTime Birthdate { get; set; }
    [Index("LastOnlineIndex")]
    public DateTime LastOnline { get; set; }

    public string NumberConfirmationCode { get; set; }

    public int Rate { get; set; }

    public int SearchRadius { get; set; }
    public int SearchLowerAge { get; set; }
    public int SearchUpperAge { get; set; }
    public int SearchMaxRate { get; set; }

    public bool AccountDisabled { get; set; }

    public virtual ICollection<Photo> Photos { get; set; }

}

我的照片 class:

public class Photo {

    public Photo() {}

    [Key]
    public int PhotoId { get; set; }
    public string Url { get; set; }
    public bool IsProfilePhoto { get; set; }

    [ForeignKey("User")]
    public int UserId { get; set; }
    public virtual User User { get; set; }

}
 public class PhotoConfiguration : EntityTypeConfiguration<Photo> {
    public PhotoConfiguration() {
        // One-to-Many
        HasRequired(s => s.User).WithMany(s => s.Photos).HasForeignKey(s => s.UserId);
    }
}

首先,如果您使用 Dapper.NET 获取实体,我不确定您为什么要发布 Entity Framework 流畅的配置。

如果要获取实体以及一对多相关实体,请查看 https://github.com/StackExchange/dapper-dot-net 上的 Dapper.NET 自述文件。本自述文件中的以下示例应该适用于您的情况:

var sql = 
@"select * from #Posts p 
left join #Users u on u.Id = p.OwnerId 
Order by p.Id";

var data = connection.Query<Post, User, Post>(sql, (post, user) => { post.Owner = user; return post;});

考虑每个 User 都有一个集合 Posts 并且您想使用获取的关联来填充该集合。您可以使用 Linq to Objects 来实现这一点:

var users = data.GroupBy(p => p.Owner.Id).Select(g =>
{
    var user = g.First().Owner;
    user.Posts = g.ToList();
    return user;
 });