Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ method syntax for multiple left join

Tags:

c#

sql

mysql

linq

Three tables are needed to be joined together.

Table [Package]

ID (int)
ContainerID (int)
Code (string)
Code2 (string)


Table [UserHasPackages]

UserID (Comes from Identity tables) (string)
PackageID (int)


Table [Container]

ID (int)
Name (string)
Description (string)

Into a viewmodel that represents an object I'd like to display in my view:

public class CustomViewModel
{
    public int ID { get; set; }
    public string Name { get; set; } // Container.Name
    public string Code { get; set; } // Package.Code
    public string Code2 { get; set; } // Package.Code2
}

But I'm having problems doing the join:

List<CustomViewModel> list = new List<CustomViewModel>();

        list = context.Packages.Join(
            context.Containers,
            p => p.ContainerID,
            c => c.ID,
            (p, c) => new { p, c})
        .Join(                                 //error is here
            context.UserHasPackages,
            a => a.p.ID,
            b => b.ApplicationUserId,
            (a, b) => new { a, b })
        .Select(f => new CustomViewModel
        {
            ID = f.p.ID,
            Name = f.c.Name,
            Code = f.p.Code,
            Code2 = f.p.Code2
        }).ToList();

Type arguments for method cannot be inherited from the usage. Try specifying the type arguments explicitly.

Is there another way to do two joins (as described) that's the more-proper way?


SOLUTION

Method based syntax is a no-go here, had to go with query syntax:

var query = (from package in context.Packages
        join container in context.Containers on package.ContainerID equals container.ID
        join userHasPackage in context.UserHasPackages on package.ID equals userHasPackage.PackageID
        where userHasPackage.UserID == "SomeUser"
        select new CustomViewModel
        {
            ID = package.ID,
            Name = container.Name,
            Code = package.Code,
            Code2 = package.Code2
        }).ToList();
like image 750
reZach Avatar asked Jul 30 '26 19:07

reZach


1 Answers

I'm assuming that you want to join the UserHasPackages table because you wanted to filter the results for a specific user (I just put in a 'SomeUser' because I'm not sure where the 'UserHasPackages.ApplicationUserId' came from) since it is not included on the view model.

I believe something like the following should work:

var list = context.Packages
    .Join(context.Containers, p => p.ContainerID, c => c.ID, (p, c) => new { p, c })
    .Join(context.UserHasPackages, pc => pc.p.ID, u => u.PackageID, (pc, u) => new { pc.p, pc.c, u })
    .Where(pcu => pcu.u.UserID == "SomeUser")
    .Select(pcu => new
    {
        pcu.p.ID,
        pcu.c.Name,
        pcu.p.Code,
        pcu.p.Code2
    });

You could also do this using the query syntax:

var query = from package in context.Packages
            join container in context.Containers on package.ContainerID equals container.ID
            join userHasPackage in context.UserHasPackages on package.ID equals userHasPackage.PackageID
            where userHasPackage.UserID == "SomeUser"
            select new
            {
                package.ID,
                container.Name,
                package.Code,
                package.Code2
            };
like image 103
a little sheep Avatar answered Aug 01 '26 09:08

a little sheep



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!