En utilisant SQL, comment puis-je hydrater des objets enfants à partir d'une seule requête?

c# dapper entity-framework sql tsql

Question

J'utilise Dapper, mais je pense que cela s'applique à SQL général:

J'ai ce qui suit:

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

Cela renvoie maintenant les résultats attendus, mais la propriété User.Photos est toujours vide. Comment puis-je hydrater cela depuis la requête?

Ma classe d'utilisateurs:

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

}

Ma classe de photo:

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

Réponse acceptée

Tout d'abord, je ne suis pas sûr de savoir pourquoi vous avez publié la configuration courante d'Entity Framework si vous utilisez Dapper.NET pour récupérer des entités.

Si vous souhaitez récupérer une entité avec des entités liées un à plusieurs, consultez le fichier Lisez-moi de Dapper.NET sur https://github.com/StackExchange/dapper-dot-net . L'exemple suivant de ce fichier Lisez-moi devrait être applicable à votre cas:

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

Considérez que chaque User possède une collection de Posts et que vous souhaitez remplir cette collection en utilisant les associations récupérées. Vous pouvez utiliser Linq to Objects pour y parvenir:

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


Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi