Query objects for one to many relationship in LINQ

自作多情 提交于 2020-01-06 07:54:35

问题


I have a problem which seems to be quite similar to
Query objects for one to many relationship in LINQ

I've been trying to solve my problem referring the above but somehow I've been failing for a long time.

The scenario
I have a model named Business which has a ICollection of Branches and also the business belongs to a particular SubCategory.

The model Looks something like

public class SubCategory
{
    public string Id { get; set; }

    public string Name { get; set; }

    public string Description { get; set; }

    public string ImageUrl { get; set; }

    public string Category_FK { get; set; }

    public Category Category { get; set; }

    [ForeignKey("SubCategory_FK")]
    public ICollection<Business> Businesses { get; set; }

    public SubCategory(){
        Businesses = new Collection<Business>();
    }
}

public class Business
{
    public string Id { get; set; }

    public string Name { get; set; }

    public string Email { get; set; }

    public string HeadquartersContact { get; set; }

    public string ImageUrl { get; set; }

    public SubCategory SubCategory { get; set; }

    public string SubCategory_FK { get; set; }
    [ForeignKey("Business_Fk")]
    public ICollection<Branch> Branches { get; set; }

    public Business()
    {
        Branches = new Collection<Branch>();
    }
}

And the Branch Model Looks like

public class Branch
{
    public string Id { get; set; }

    public string Name { get; set; }

    public string Phone { get; set; }

    public string ImageUrl { get; set; }

    public Business Business { get; set; }

    public string Business_Fk { get; set; }

    [ForeignKey("Location_FK")]
    public Location Location { get; set; }

    public string Location_FK { get; set; }

    [ForeignKey("Branch_FK")]
    public ICollection<BranchImage> BranchImages { get; set; }

    public Branch()
    {
        BranchImages = new Collection<BranchImage>();
    }
}

Every branch can have one location. So below is the Location Model

public class Location
    {
        public string Id { get; set; }

        public string Name { get; set; }

        public decimal Lattitude { get; set; }

        public decimal Longitude { get; set; }

        public SubLocality SubLocality { get; set; }

        public string SubLocality_FK { get; set; }

        public Branch Branch { get; set; }

        public Location()
        {
        }
    }

A SubLocality Can have ICollection of Locations. Here is the SubLocality Model

public class SubLocality
{
    public string Id { get; set; }

    public string Name { get; set; }

    public Locality Locality { get; set; }

    public string Locality_FK { get; set; }

    [ForeignKey("SubLocality_FK")]
    public ICollection<Location> Locations { get; set; }

    public SubLocality()
    {
        Locations = new Collection<Location>();
    }


}

Localities can have ICollection of Sublocality

public class Locality
{
    public string Id { get; set; }

    public string Name { get; set; }

    public City City { get; set; }

    public string City_FK { get; set; }
    [ForeignKey("Locality_FK")]
    public ICollection<SubLocality> SubLocalities { get; set; }

    public Locality()
    {
        SubLocalities = new Collection<SubLocality>();
    }
}

A City can have ICollection of Localities.

public class City
{
    public string Id { get; set; }

    public string Name { get; set; }

    public State State { get; set; }

    public string State_FK { get; set; }
    [ForeignKey("City_FK")]
    public ICollection<Locality> Localities { get; set; }

    public City()
    {
        Localities = new Collection<Locality>();
    }
}

And Lastly a state can have ICollection of cities.

public class State
{
    public string Id { get; set; }

    public string Name { get; set; }

    [ForeignKey("State_FK")]
    public ICollection<City> Cities { get; set; }

    public State()
    {
        Cities = new Collection<City>();
    }
}

Here is my DataContext whose instances my am using in the query to fetch data.

public class DataContext : DbContext
{
    public DataContext(DbContextOptions<DataContext> options): base (options)
    {

    }

    //-------Business_Info_Models----------------
    public DbSet<Branch> Branches { get; set; }
    public DbSet<BranchImage> BranchImages { get; set; }
    public DbSet<Business> Businesses { get; set; }

    //-------Category_Info_Models----------------
    public DbSet<Category> Categories { get; set; }
    public DbSet<SubCategory> SubCategories { get; set; }

    //-------------Location_Info_Models----------------
    public DbSet<City> Cities { get; set; }
    public DbSet<Locality> Localities { get; set; }
    public DbSet<Location> Locations{ get; set; }
    public DbSet<State> States { get; set; }
    public DbSet<SubLocality> SubLocalities { get; set; }
}

The requirement
Now I need to query for a businesses of a particular subcategory, and also get all the branches(like one business can have 8 branches, 5 branches etc). It's location, sublocation, city, state (To mention I get all this data from different tables by using join in LINQ).

To satisfy this requirement, I am using a DTO (Data Transfer Object).

public class AddBusinessDto
{
    public string Id { get; set; }

    public string Name { get; set; }

    public string Email { get; set; }

    public string HeadquartersContact { get; set; }

    public string ImageUrl { get; set; }

    public string SubCategory_FK  { get; set; }

    public ICollection<AddBranchDto> Branches { get; set; }
    //public ICollection<AddLocationsDto> Locations {get; set; }
}

public class AddBranchDto
{
    public string Id { get; set; }

    public string Name { get; set; }

    public string Phone { get; set; }

    public string ImageUrl { get; set; }

    public AddLocationsDto Location { get; set; }
    public string Location_FK { get; set; }
}

The LINQ Query

IQueryable<BusinessDto> query =  (from business in _context.Businesses
        join subcategory in _context.SubCategories on business.SubCategory_FK equals subcategory.Id
        join branch in _context.Branches on business.Id equals branch.Business_Fk 
        join location in _context.Locations on branch.Location_FK equals location.Id
        join sublocal in _context.SubLocalities on location.SubLocality_FK equals sublocal.Id
        join locality in _context.Localities on sublocal.Locality_FK equals locality.Id
        join city in _context.Cities on locality.City_FK equals city.Id
        join state in _context.States on city.State_FK equals state.Id
        where business.SubCategory_FK == subCatId
        select new BusinessDto() {
            Id = business.Id,
            Name = business.Name,
            HeadquartersContact = business.HeadquartersContact,
            Location = location.Name,
            Sublocality = sublocal.Name,
            Locality = locality.Name,
            City = city.Name,
            State = state.Name,
            Email = business.Email,

            Branches = business.Branches
                        .Select(branches => 
                        new BranchDto{Id = branches.Id, Name = branches.Name, Phone = branches.Phone})
                        .Distinct()
                        .ToList()
        });

I am almost there to the result but this the BUG with this query is :

The above business in the SS has 8 branches. Ideally I should ne getting just one card on th UI which shows data of 8 branches when I hover the branch icon.

But the query gives me 8 cards of such sort. How do I solve this. Pleae help!

来源:https://stackoverflow.com/questions/53803986/query-objects-for-one-to-many-relationship-in-linq

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!