664 Stimmen

LEFT OUTER JOIN in LINQ

Wie führt man eine linke äußere Verknüpfung in C# LINQ to objects ohne Verwendung von join-on-equals-into Klauseln? Gibt es eine Möglichkeit, dies zu tun mit where Klausel? Richtiges Problem: Für inner join ist einfach und ich habe eine Lösung wie diese

List<JoinPair> innerFinal = (from l in lefts from r in rights where l.Key == r.Key
                             select new JoinPair { LeftId = l.Id, RightId = r.Id})

aber für die linke äußere Verbindung brauche ich eine Lösung. Meine ist etwas wie dieses, aber es funktioniert nicht

List< JoinPair> leftFinal = (from l in lefts from r in rights
                             select new JoinPair { 
                                            LeftId = l.Id, 
                                            RightId = ((l.Key==r.Key) ? r.Id : 0
                                        })

donde JoinPair ist eine Klasse:

public class JoinPair { long leftId; long rightId; }

3 Stimmen

Können Sie ein Beispiel dafür geben, was Sie zu erreichen versuchen?

0 Stimmen

Normale linke äußere Verknüpfung ist so etwas wie dieses: var a = from b in bb join c in cc on b.bbbbb equals c.ccccc into dd from d in dd.DefaultIfEmpty() select b.sss; Meine Frage ist es eine Möglichkeit zu tun, dass ohne Verwendung von join-on-equals-into-Klauseln etwas wie dieses var a = from b in bb from c in cc where b.bbb == c.cccc ... und so weiter...

2 Stimmen

Sicher gibt es, aber Sie sollten ein Beispiel für Ihren Code posten, den Sie bereits haben, damit die Leute Ihnen eine bessere Antwort geben können

2voto

John Fullman Punkte 51

Hier ist eine Version der Erweiterungsmethode Lösung mit IQueryable anstelle von IEnumerable

public class OuterJoinResult<TLeft, TRight>
{
    public TLeft LeftValue { get; set; }
    public TRight RightValue { get; set; }
}

public static IQueryable<TResult> LeftOuterJoin<TLeft, TRight, TKey, TResult>(this IQueryable<TLeft> left, IQueryable<TRight> right, Expression<Func<TLeft, TKey>> leftKey, Expression<Func<TRight, TKey>> rightKey, Expression<Func<OuterJoinResult<TLeft, TRight>, TResult>> result)
{
    return left.GroupJoin(right, leftKey, rightKey, (l, r) => new { l, r })
          .SelectMany(o => o.r.DefaultIfEmpty(), (l, r) => new OuterJoinResult<TLeft, TRight> { LeftValue = l.l, RightValue = r })
          .Select(result);
}

1 Stimmen

Und wie so oft bei Erweiterungsmethoden wird der Aufruf der Methode komplexer als die Verwendung der grundlegenden LINQ-Methoden selbst. Aufruf von GroupJoin in Code ist überhaupt nicht schwer, vor allem nicht mit Abfragesyntax.

2voto

ozkary Punkte 2178

Dies ist eine SQL-Syntax im Vergleich zur LINQ-Syntax für innere und linke äußere Joins. Linker äußerer Join:

http://www.ozkary.com/2011/07/linq-to-entity-inner-and-left-joins.html

"Das folgende Beispiel führt eine Gruppenverknüpfung zwischen Produkt und Kategorie durch. Dies ist im Wesentlichen die linke Verknüpfung. Der into-Ausdruck gibt auch dann Daten zurück, wenn die Kategorietabelle leer ist. Um auf die Eigenschaften der Kategorietabelle zuzugreifen, müssen wir nun aus dem aufzählbaren Ergebnis auswählen, indem wir die Anweisung from cl in catList.DefaultIfEmpty() hinzufügen.

1voto

Hamid Punkte 19

Left Outer Joins in Linq C# durchführen // Durchführen von Left Outer Joins

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

class Child
{
    public string Name { get; set; }
    public Person Owner { get; set; }
}
public class JoinTest
{
    public static void LeftOuterJoinExample()
    {
        Person magnus = new Person { FirstName = "Magnus", LastName = "Hedlund" };
        Person terry = new Person { FirstName = "Terry", LastName = "Adams" };
        Person charlotte = new Person { FirstName = "Charlotte", LastName = "Weiss" };
        Person arlene = new Person { FirstName = "Arlene", LastName = "Huff" };

        Child barley = new Child { Name = "Barley", Owner = terry };
        Child boots = new Child { Name = "Boots", Owner = terry };
        Child whiskers = new Child { Name = "Whiskers", Owner = charlotte };
        Child bluemoon = new Child { Name = "Blue Moon", Owner = terry };
        Child daisy = new Child { Name = "Daisy", Owner = magnus };

        // Create two lists.
        List<Person> people = new List<Person> { magnus, terry, charlotte, arlene };
        List<Child> childs = new List<Child> { barley, boots, whiskers, bluemoon, daisy };

        var query = from person in people
                    join child in childs
                    on person equals child.Owner into gj
                    from subpet in gj.DefaultIfEmpty()
                    select new
                    {
                        person.FirstName,
                        ChildName = subpet!=null? subpet.Name:"No Child"
                    };
                       // PetName = subpet?.Name ?? String.Empty };

        foreach (var v in query)
        {
            Console.WriteLine($"{v.FirstName + ":",-25}{v.ChildName}");
        }
    }

    // This code produces the following output:
    //
    // Magnus:        Daisy
    // Terry:         Barley
    // Terry:         Boots
    // Terry:         Blue Moon
    // Charlotte:     Whiskers
    // Arlene:        No Child

https://dotnetwithhamid.blogspot.in/

0voto

class Program
{
    List<Employee> listOfEmp = new List<Employee>();
    List<Department> listOfDepart = new List<Department>();

    public Program()
    {
        listOfDepart = new List<Department>(){
            new Department { Id = 1, DeptName = "DEV" },
            new Department { Id = 2, DeptName = "QA" },
            new Department { Id = 3, DeptName = "BUILD" },
            new Department { Id = 4, DeptName = "SIT" }
        };

        listOfEmp = new List<Employee>(){
            new Employee { Empid = 1, Name = "Manikandan",DepartmentId=1 },
            new Employee { Empid = 2, Name = "Manoj" ,DepartmentId=1},
            new Employee { Empid = 3, Name = "Yokesh" ,DepartmentId=0},
            new Employee { Empid = 3, Name = "Purusotham",DepartmentId=0}
        };

    }
    static void Main(string[] args)
    {
        Program ob = new Program();
        ob.LeftJoin();
        Console.ReadLine();
    }

    private void LeftJoin()
    {
        listOfEmp.GroupJoin(listOfDepart.DefaultIfEmpty(), x => x.DepartmentId, y => y.Id, (x, y) => new { EmpId = x.Empid, EmpName = x.Name, Dpt = y.FirstOrDefault() != null ? y.FirstOrDefault().DeptName : null }).ToList().ForEach
            (z =>
            {
                Console.WriteLine("Empid:{0} EmpName:{1} Dept:{2}", z.EmpId, z.EmpName, z.Dpt);
            });
    }
}

class Employee
{
    public int Empid { get; set; }
    public string Name { get; set; }
    public int DepartmentId { get; set; }
}

class Department
{
    public int Id { get; set; }
    public string DeptName { get; set; }
}

OUTPUT

0voto

BionicCyborg Punkte 9

Wenn Sie etwas verknüpfen und filtern müssen, können Sie dies außerhalb der Verknüpfung tun. Das Filtern kann nach der Erstellung der Sammlung erfolgen.

In diesem Fall, wenn ich dies in der Join-Bedingung tue, reduziere ich die Zeilen, die zurückgegeben werden.

Ternäre Bedingung wird verwendet (= n == null ? "__" : n.MonDayNote,)

  • Wenn das Objekt null (also keine Übereinstimmung), dann geben Sie zurück, was nach der ? . __ in diesem Fall.

  • Andernfalls wird das zurückgegeben, was nach der : , n.MonDayNote .

Dank der anderen Mitwirkenden habe ich dort mit meinem eigenen Problem begonnen.


        var schedLocations = (from f in db.RAMS_REVENUE_LOCATIONS
              join n in db.RAMS_LOCATION_PLANNED_MANNING on f.revenueCenterID equals

                  n.revenueCenterID into lm

              from n in lm.DefaultIfEmpty()

              join r in db.RAMS_LOCATION_SCHED_NOTE on f.revenueCenterID equals r.revenueCenterID
              into locnotes

              from r in locnotes.DefaultIfEmpty()
              where f.LocID == nLocID && f.In_Use == true && f.revenueCenterID > 1000

              orderby f.Areano ascending, f.Locname ascending
              select new
              {
                  Facname = f.Locname,
                  f.Areano,
                  f.revenueCenterID,
                  f.Locabbrev,

                  //  MonNote = n == null ? "__" : n.MonDayNote,
                  MonNote = n == null ? "__" : n.MonDayNote,
                  TueNote = n == null ? "__" : n.TueDayNote,
                  WedNote = n == null ? "__" : n.WedDayNote,
                  ThuNote = n == null ? "__" : n.ThuDayNote,

                  FriNote = n == null ? "__" : n.FriDayNote,
                  SatNote = n == null ? "__" : n.SatDayNote,
                  SunNote = n == null ? "__" : n.SunDayNote,
                  MonEmpNbr = n == null ? 0 : n.MonEmpNbr,
                  TueEmpNbr = n == null ? 0 : n.TueEmpNbr,
                  WedEmpNbr = n == null ? 0 : n.WedEmpNbr,
                  ThuEmpNbr = n == null ? 0 : n.ThuEmpNbr,
                  FriEmpNbr = n == null ? 0 : n.FriEmpNbr,
                  SatEmpNbr = n == null ? 0 : n.SatEmpNbr,
                  SunEmpNbr = n == null ? 0 : n.SunEmpNbr,
                  SchedMondayDate = n == null ? dMon : n.MondaySchedDate,
                  LocNotes = r == null ? "Notes: N/A" : r.LocationNote

              }).ToList();
                Func<int, string> LambdaManning = (x) => { return x == 0 ? "" : "Manning:" + x.ToString(); };
        DataTable dt_ScheduleMaster = PsuedoSchedule.Tables["ScheduleMasterWithNotes"];
        var schedLocations2 = schedLocations.Where(x => x.SchedMondayDate == dMon);

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X