Я создаю приложение API ASP.NET Core и полагаюсь на EF Core. У меня есть такие объекты, которые определены следующим образом:
public class AppUser : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
[InverseProperty(nameof(Post.Author))]
public ICollection<Post> Posts { get; set; } = new List<Post>();
}
public class Post
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string AuthorId { get; set; }
[ForeignKey("AuthorId")]
public virtual AppUser Author { get; set; }
[InverseProperty(nameof(Like.Post))]
public ICollection<Like> Likes { get; set; } = new List<Like>();
[InverseProperty(nameof(Comment.Post))]
public ICollection<Comment> Comments { get; set; } = new List<Comment>();
}
Где Comment и Like - некоторые другие сущности. Обратите внимание, что я упростил сущности для краткости. Затем я хочу получить Posts пользователя, но также включить Likes и Comments, полученные в сообщении. Итак, я сделал что-то вроде этого:
return _context.Users
.Include(u => u.Location)
.Include(u => u.Posts)
.ThenInclude(p => p.Comments)
.ThenInclude(c => c.Owner)
.Include(u => u.Posts)
.ThenInclude(p => p.Likes)
.ThenInclude(l => l.Giver)
.Where(u => u.Id == userId)
.FirstOrDefault();
Теперь это работает нормально, но, как видите, я дважды звонил .Include(u = u.Posts). Есть ли способ дважды вызвать ThenInclude для одного и того же свойства, не записывая дважды оператор Include?





Now, this works fine, but as you can see I'm calling .Include(u = u.Posts) twice. Is there a way to call ThenInclude twice on same property, without actually writing the Include statement also twice?
Дважды вызвать Include(u => u.Posts) - это правильный способ сделать это.
От Документы EF Core ... акцент на последней фразе.
You may want to include multiple related entities for one of the entities that is being included. For example, when querying
Blogs, you includePostsand then want to include both theAuthorandTagsof thePosts. To do this, you need to specify each include path starting at the root. For example,Blog -> Posts -> AuthorandBlog -> Posts -> Tags. This does not mean you will get redundant joins, in most cases EF will consolidate the joins when generating SQL.
using (var context = new BloggingContext())
{
var blogs = context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.Include(blog => blog.Posts)
.ThenInclude(post => post.Tags)
.ToList();
}
Я набрал "Также включить", не зная, что такого не существует !!
Вы не можете использовать ThenInclude с несколькими свойствами навигации. У вас должен быть Include.
Вот для этого открыт ошибка.
Хорошее время для Microsoft реализовать
AlsoInclude(), чтобы вам не приходилось писать один и тот же оператор include несколько раз.