使用Sql,如何在单个Query中水合子对象?

时间:2015-02-15 20:43:01

标签: c# sql entity-framework tsql dapper

我正在使用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属性始终为空。如何在查询中对此进行保湿?

我的用户类:

[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; }

}

我的照片类:

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);
    }
}

1 个答案:

答案 0 :(得分:0)

首先,如果您使用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;
 });