Çözüldü ASP.NET Core 5.0 Entity Framework Left Join LINQ sorgusu çalışmıyor

Bu konu çözüldü olarak işaretlenmiştir. Çözülmediğini düşünüyorsanız konuyu rapor edebilirsiniz.

Burak Temelkaya

Kilopat
Katılım
13 Ekim 2016
Mesajlar
1.156
Makaleler
1
Çözümler
5
Yer
İstanbul
Daha fazla  
Sistem Özellikleri
İŞLEMCİ: AMD Ryzen 5 7600
İŞLEMCİ SOĞUTUCU: Cooler Master Hyper 212 Spectrum Rainbow LED 120mm Hava Soğutucu
ANAKART: MSI Pro B650M-A WiFi AM5
EKRAN KARTI: MSI Radeon RX 6800 Gaming Z Trio 16G V1 16GB
RAM: Kingston Fury Beast 16 + 8 GB 6000MHz CL40 DDR5 Ram
SSD: Samsung 980 1TB + Kingston KC3000 2TB
KASA: VENTO Neptune VG07F RGB Siyah Mid Tower Gaming Kasa
PSU: FSP Hyper Pro H3-650 650W 80+ Bronze
Cinsiyet
Erkek
Meslek
Yazılım Geliştirici
Merhaba böyle bir linq kodum var. Entity Framework'ün code first 5.17 versiyonunu kullanıyorum.

C#:
var query = from blog in _context.Set<Blog>().Where(filter)
 join category in _context.Set<Category>()
 on blog.CategoryID equals category.CategoryID
 join comment in _context.Set<Comment>()
 on blog.BlogID equals comment.BlogID into commentBlogs
 from comment in commentBlogs.DefaultIfEmpty()

 select new BlogDto.
 {
 Blog = blog,
 CommentCount = commentBlogs == null ? 0 : commentBlogs.Count(),
 BlogStar = comment.BlogScore,
 CategoryName = category.CategoryName,
 };

Bu kodu çalıştırmaya çalışınca böyle bir hata veriyor.

Kod:
InvalidOperationException: variable 'commentBlogs' of type 'System.Collections.Generic.IEnumerable`1[EntityLayer.Concrete.Comment]' referenced from scope '', but it is not defined

Buradaki amacım şu; bloglardaki yorum sayısını comment tablosundaki yorumlara göre almak.
Deneyebileceğim her şeyi denedim ama bir türlü çözemedim sorunu yardımcı olursanız sevinirim.
Entitiylerim şu şekilde.

Blog.

C#:
[Key]
 public int BlogID { get; set; }
 public string BlogTitle { get; set; }
 public string BlogContent { get; set; }
 public string BlogThumbnailImage { get; set; }
 public string BlogImage { get; set; }
 public DateTime BlogCreateDate { get; set; }
 public bool BlogStatus { get; set; }
 public int CategoryID { get; set; }
 public Category Category { get; set; }
 public int WriterID { get; set; }
 public AppUser Writer { get; set; }
 public virtual ICollection<Comment> Comments { get; set; }

Comment.

C#:
[Key]
 public int CommentID { get; set; }
 public string CommentUserName { get; set; }
 public string CommentTitle { get; set; }
 public string CommentContent { get; set; }
 public DateTime CommentDate { get; set; }
 public int BlogScore { get; set; }
 public bool CommentStatus { get; set; }
 public int? BlogID { get; set; }
 public Blog Blog { get; set; }

Context'te şu şekilde ilişkilerini verdim.

C#:
 modelBuilder.Entity<Blog>()
 .HasMany(x => x.Comments)
 .WithOne(x => x.Blog)
 .HasForeignKey(x => x.BlogID);

 modelBuilder.Entity<Comment>()
 .HasOne(x => x.Blog)
 .WithMany(x => x.Comments)
 .HasForeignKey(x => x.BlogID);

Count içerisine lambda ile girip x=> x.blogId== blog.BlogId gibi bir şey vermeye çalışınca da hata veriyor.

Veritabanın backupını bırakıyorum. CoreBlogDb.bak

Merhaba uzun bir süre sonra izlediğim eğitim videolarından farkedip bu kodu çalışır hale getirdim sonradan konuyu görüp çözüm arayan varsa işine yarar diye yazıyorum.

C#:
var query =
Context.Blogs
.Include(x => x.Category)
.Include(x => x.Comments)
.Select(blog =>
new BlogCategoryandCommentCountDto
{
    BlogID = blog.BlogID,
    BlogContent = blog.BlogContent,
    BlogImage = blog.BlogImage,
    BlogThumbnailImage = blog.BlogThumbnailImage,
    BlogTitle = blog.BlogTitle,
    BlogCreateDate = blog.BlogCreateDate,
    BlogStatus = blog.BlogStatus,
    CategoryID = blog.Category.CategoryID,
    CategoryName = blog.Category.CategoryName,
    CategoryStatus = blog.Category.CategoryStatus,
    CommentCount = blog.Comments.Count > 0 ? blog.Comments.Count : 0,
    CommentScore = blog.Comments.Count > 0 ? blog.Comments.Average(x => x.BlogScore) : 0
})
.OrderByDescending(x => x.BlogID).AsQueryable();

query = filter != null ? query.Where(filter) : query;

query = take != 0 ? query.Skip(skip).Take(take) : query;

return await query.ToListAsync();

BlogCategoryandCommentCountDto nesnesinin içeriği bu şekilde.

C#:
public class BlogCategoryandCommentCountDto : Blog
{
    public string CategoryName { get; set; }

    public bool CategoryStatus { get; set; }

    public int CommentCount { get; set; } = 0;

    public double CommentScore { get; set; } = 0;
}

Son olarak eğer her Comment için özel olarak sorgulama yapmak istiyorsanız Full Join yani Union kullanmanız gerekiyor. Bunun için sorgumu şu şekilde değiştirdim.

C#:
var leftQuery = from blog in Context.Blogs
                join category in Context.Categories
                    on blog.CategoryID equals category.CategoryID
                join comment in Context.Comments.Where(x => x.CommentStatus == commentStatus)
                    on blog.BlogID equals comment.BlogID into BlogComments
                from comment in BlogComments.DefaultIfEmpty()
                select new BlogCategoryandCommentCountDto
                {
                    BlogID = blog.BlogID,
                    BlogContent = blog.BlogContent,
                    BlogImage = blog.BlogImage,
                    BlogThumbnailImage = blog.BlogThumbnailImage,
                    BlogTitle = blog.BlogTitle,
                    BlogCreateDate = blog.BlogCreateDate,
                    BlogStatus = blog.BlogStatus,
                    CategoryID = blog.Category.CategoryID,
                    CategoryName = blog.Category.CategoryName,
                    CategoryStatus = blog.Category.CategoryStatus,
                    CommentCount = comment != null ? blog.Comments.Count : 0,
                    CommentScore = comment != null ? blog.Comments.Average(x => x.BlogScore) : 0,
                    CommentStatus = comment == null ? false : comment.CommentStatus
                };

var rightQuery = from comment in Context.Comments
                 join category in Context.Categories
                     on comment.Blog.CategoryID equals category.CategoryID
                 join blog in Context.Blogs
                     on comment.BlogID equals blog.BlogID into BlogComments
                 from blog in BlogComments.DefaultIfEmpty()
                 select new BlogCategoryandCommentCountDto
                 {
                     BlogID = blog.BlogID,
                     BlogContent = blog.BlogContent,
                     BlogImage = blog.BlogImage,
                     BlogThumbnailImage = blog.BlogThumbnailImage,
                     BlogTitle = blog.BlogTitle,
                     BlogCreateDate = blog.BlogCreateDate,
                     BlogStatus = blog.BlogStatus,
                     CategoryID = blog.Category.CategoryID,
                     CategoryName = blog.Category.CategoryName,
                     CategoryStatus = blog.Category.CategoryStatus,
                     CommentCount = comment != null ? blog.Comments.Count : 0,
                     CommentScore = comment != null ? blog.Comments.Average(x => x.BlogScore) : 0,
                     CommentStatus = comment == null ? false : comment.CommentStatus
                 };

var query = leftQuery.Union(rightQuery).OrderByDescending(x => x.BlogID).AsQueryable();

query = filter != null ? query.Where(filter) : query;

query = take != 0 ? query.Skip(skip).Take(take) : query;

return await query.ToListAsync();
 
Son düzenleme:

Geri
Yukarı