简体   繁体   中英

Linq query doesn't work in C# ASP.NET Core when I use full outer join

These are my classes map to my database

public class Course
{
    [Key]
    public int CourseID { get; set; }
    [Required]
    public string Title { get; set; }
    [Required]
    public string Description { get; set; }
    public bool? IsPublish { get; set; }
    public bool? HaveSupport { get; set; }
    [Required]
    public string TimeDuration { get; set; }
    public string Price { get; set; }
    public int CoachID { get; set; }
    public DateTime? PublishDate { get; set; }
    public bool? Delete { get; set; }
    public int PublisherID { get; set; }

    public virtual List<Course_Coach> Course_Coaches { get; set; }
    public virtual List<Course_Publisher> Course_Publishers { get; set; }
    public virtual List<Course_Category> Course_Categories { get; set; }
}

public class Course_Publisher
{
    public int CourseID { get; set; }
    public int PublisherID { get; set; }

    public virtual Course Course { get; set; }
    public virtual Publisher Publisher { get; set; }
}

public class Publisher
{
    [Key]
    public int PublisherID { get; set; }

    [Required]
    public string PublisherName { get; set; }

    public string Description { get; set; }
    public string Address { get; set; }
    public string PhoneNumber { get; set; }

    public virtual List<Coach> Coaches { get; set; }
    public virtual List<Course_Publisher> Course_Publishers { get; set; }
}

public class Course_Coach
{
    public int CourseID { get; set; }
    public int CoachID { get; set; }

    public virtual Course Course { get; set; }
    public virtual Coach Coach { get; set; }
}

public class Coach
{
    [Key]
    public int CoachID { get; set; }

    [Required]
    public string Name { get; set; }

    [Required]
    public string Family { get; set; }

    public string Description { get; set; }

    public string PhonNumber { get; set; }
    public DateTime? RegisterDate { get; set; }

    public virtual List<Course_Coach> Course_Coaches { get; set; }
    public virtual Publisher Publisher { get; set; }
    public virtual List<Coach_CoachCategory> Coach_CoachCategories { get; set; }
}

And my problem is: however, I tried several models, but each time I had trouble obtaining publishername and coachname values.

This is my query:

public List<CoursesIndexViewModel> GetAllCourses()
{
    List<CoursesIndexViewModel> viewModel = new List<CoursesIndexViewModel>();

    string categoryName = "";
    string publisherName = "";
    string coachName = "";

    var getAllCourses = (from c in _Context.Courses
                         join coachCourse in _Context.Course_Coaches on c.CourseID equals coachCourse.CourseID into coachcourseinto 
                         from coach_course in coachcourseinto.DefaultIfEmpty()
                         join justcoach in _Context.Coaches on coach_course.CoachID equals justcoach.CoachID into coachinto 
                         from coach in coachinto.DefaultIfEmpty()
                         join pc in _Context.Course_Publishers on c.CourseID equals pc.CourseID into pcinto 
                         from publisher_course in pcinto.DefaultIfEmpty()
                         join p in _Context.Publishers on publisher_course.PublisherID equals p.PublisherID into publisherinto 
                         from publisher in publisherinto.DefaultIfEmpty()
                         join category_ccourse in _Context.Course_Categories on c.CourseID equals category_ccourse.CourseID into coursecategory 
                         from categories in coursecategory.DefaultIfEmpty()
                         join category in _Context.Categories on categories.CategoryID equals category.CategoryID into categoryinto 
                         from justcategory in categoryinto.DefaultIfEmpty()
                         where (c.Delete == false)
                         select new
                             {
                                 c.CourseID,
                                 c.Title,
                                 c.Description,
                                 c.Price,
                                 c.TimeDuration,
                                 c.IsPublish,
                                 c.HaveSupport,
                                 c.PublishDate,
                                 c.CoachID,
                                 c.PublisherID,
                                 publishName= c.PublisherID==publisher.PublisherID ? publisher.PublisherName : publisher.PublisherName,
                                 coachName=c.CoachID==coach.CoachID ? coach.Name+" "+coach.Family : coach.Name+" "+coach.Family,
                                 //CoachName=coach_course != null ? coach.Name+" "+coach.Family : "",
                                 //PublisherName=publisher_course !=  null ? publisher.PublisherName : "",
                                 //CoachName=coach_course != null ? coach.Name+" " +coach.Family : coach.Name+" "+coach.Family,
                                 //PublisherName=publisher_course != null ? publisher.PublisherName : publisher.PublisherName,
                                 CategoryName=categories != null ? justcategory.CategoryName : "",

                             }).GroupBy(g=>g.CourseID).Select(a=>new {CourseID=a.Key,CourseGroup=a }).ToList();

        foreach(var it in getAllCourses)
        {
            categoryName = "";
            coachName = "";
            publisherName = "";
            foreach(var item in it.CourseGroup.Select(a => a.CategoryName).Distinct())
            {
                if (categoryName == null)
                {
                    categoryName = item;
                }
                else
                {
                    categoryName = categoryName + " - " + item;
                }
            }

            foreach(var item in it.CourseGroup.Select(c => c.coachName).Distinct())
            {
                if(coachName == null)
                {
                    coachName = item;
                }
            }

            foreach(var item in it.CourseGroup.Select(p => p.publishName).Distinct())
            {
                if (publisherName == null)
                {
                    publisherName = item;
                }
            }

            CoursesIndexViewModel vM = new CoursesIndexViewModel()
            {
                CourseID = it.CourseGroup.First().CourseID,
                Title = it.CourseGroup.First().Title,
                Description = it.CourseGroup.First().Description,
                Price = it.CourseGroup.First().Price,
                TimeDuration = it.CourseGroup.First().TimeDuration,
                IsPublish = it.CourseGroup.First().IsPublish,
                HaveSupport = it.CourseGroup.First().HaveSupport,
                PublishDate = it.CourseGroup.First().PublishDate,
                CoachID = coachName,
                PublisherID = publisherName,
                CategoryID = categoryName
            };

            viewModel.Add(vM);
        }

        return viewModel;
    }

I have tried both the non-using method and the full outer join assisted method, but each time I come to an incomplete result and do not understand the reason. Because one of them full outer join is working properly

Where is my problem? Because I really do not understand why it does not work properly. Thankful

I have tried both the non-using method and the full outer join assisted method, but each time I come to an incomplete result and do not understand the reason.

It seems that you are using where clause, whether the issue is related it, try to remove it and check whether you could get the complete result.

Based on your code, I have created a sample and add the following data (the course table, publisher table and Coach table contains many-to-many relationship ):

在此处输入图像描述

Then, using the following query statement to query the data:

        var result = (from c in _context.Courses
                     join coachCourse in _context.Course_Coaches on c.CourseID equals coachCourse.CourseID into coachcourseinto
                     from coach_course in coachcourseinto.DefaultIfEmpty()
                     join justcoach in _context.Coaches on coach_course.CoachID equals justcoach.CoachID into coachinto
                     from coach in coachinto.DefaultIfEmpty()
                     join pc in _context.Course_Publishers on c.CourseID equals pc.CourseID into pcinto
                     from publisher_course in pcinto.DefaultIfEmpty()
                     join p in _context.Publishers on publisher_course.PublisherID equals p.PublisherID into publisherinto
                     from publisher in publisherinto.DefaultIfEmpty()
                     select new
                     {
                         c.CourseID,
                         c.Title,
                         c.Description,     
                         c.CoachID,
                         c.PublisherID,
                         publishName = c.PublisherID == publisher.PublisherID ? publisher.PublisherName : publisher.PublisherName,
                         coachName = c.CoachID == coach.CoachID ? coach.Name + " " + coach.Family : coach.Name + " " + coach.Family, 
                     }).ToList();

The result like this: it return all elements in the first table (Course).

在此处输入图像描述

Besides, from your code, after getting the all the course, you will group the result by the courseID, and loop through the course to add a specified separator ('-') between each categoryName(or publisherName and coachName). I suggest you could try to use InClude and ThenInClude method to query the related data .

        var result2 = _context.Courses
            .Include(c => c.Course_Coaches).ThenInclude(d => d.Coach)
            .Include(c => c.Course_Publishers).ThenInclude(d => d.Publisher)
            .Select(c => new
            {
                Title = c.Title,
                Desctiption = c.Description,
                Publisher = string.Join(",", c.Course_Publishers.Select(d => d.Publisher.PublisherName)),
                Coach = string.Join(",", c.Course_Coaches.Select(d => d.Coach.Name))
            }).ToList();

The result like this: add the separator (',') between the value.

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM