Linq - Select aus zwei Tabellen


julia23

Mitglied
Hallo,

ich will eigentlich nur eine einfache select anfrage aus zwei Tabellen machen.

z.b
"Select COUNT(*) from dbo.Tabelle1 t1, dbo.Tabelle2 t2";

Wenn ich das als "Linq" schreiben will würde ich folgendes machen.
var beispiel = (from t1 t2 in db.t1, db t2
select t1, t2).Count();

Das funktioniert aber nicht so. Es ist nicht mal von der Syntax korrekt. Leider kann ich
dazu nichts im Internet finden. Kann mir bitte jemand von euch weiterhelfen?
 

Cromon

Erfahrenes Mitglied
Halo julia23

Was ist denn db und entsprechend db.t1 bzw db.t2? Ein Beispiel:
C#:
var arr = new[] {1, 2, 3, 4, 5, 6, 7, 8};
var arr2 = new[] {100, 101, 102, 103, 104, 105, 106, 107, 108};
var count = (from a in arr select a).Union(from b in arr2 select b).Count();

Wenn du eine Bedingung für den join hast:¨
C#:
var count = (from a in arr join b in arr2 on a equals (b % 100) select a).Count();

Grüsse
Cromon
 

julia23

Mitglied
Hallo,

vielen Dank schonmal für deine erste Antwort. Ich habe unten mal ein Beispiel gemacht, was so ähnlich ist wie meine tatsächliche Abfrage:

Tabelle Produkt:

ProduktId Produkt IsActive DeleteDate

1 Hammer 1 250115

2 Meisel 1 250115

3 Nagel 1 250115

4 Schraube 0 250115

5 Laim 0 240115



Verkauf

VerkaufId Kunde ProduktId NichtRückläufig

10 Siggi 1 1

12 Franz 2 1

13 Bernd 3 0



//Ich will nun alle die Verkäufe,

Select * from Produkt p, Verkauf v

//indem das Produkt aktiv ist und ab dem 25.1 eingespeichert wurde

where p. IsActive =1 and p. DeleteDate>240115

//und das nicht Rückläufig ist

and v. NichtRückläufig=1

Resultat:

10 Siggi 1 1

12 Franz 2 1



In Anlehnung an deine Antwort, bräuchte ich dann die Variante mit Union:

public String GetEinkäufeAktuell()

{

//Db führt zu meiner Enitätsklasse

using (var db = new Models.EntityClasses.ReportContext())

{

var verkaufsbeispiel = (from p in db.Produkts where p. IsActive ==1 and p. DeleteDate>240115 select p).Union(from v in db.Verkaufs where v.NichtRückläufig=1 select v).Count();

return verkaufsbeispiel;

}

}


Jetzt müsste das doch so funktionieren oder?

Wann brauche ich den überhaupt einen Join? Wo wäre der Unterschied? Bei einer 1:n Relation kann ich doch immer einfach mit Where abfagen oder ist das egal?

Oder muss ich bei Bedingungen immer die join variante wählen? Das war doch vorher nicht so oder?
 

Cromon

Erfahrenes Mitglied
Hallo julia23

Was dein Beispiel macht ist folgendes:
Zuerst wähle alle Produkte aus db.Produkts aus bei denen IsActive 1 ist und DeleteDate > 240115. Anschliessend füge da alle Elemente aus db.Verkaufs an bei denen NichtRückläufig 1 ist. Dabei gibt es keine Bedinungen zwischen den beiden. Es werden also alle aktiven, eingespeicherten Produkte ausgegeben sowie alle nicht rückläufigen Verkäufe. Du möchtest diese beiden jedoch verbinden, dazu verwendest du den Join, so wie du es auch in SQL machen würdest.

Ein Beispiel (das man vermutlich gerade bei der Datumsüberprüfung noch vereinfachen könnte):
C#:
            var products = new[]
            {
                new Product {Id = 1, Name = "Hammer"},
                new Product {Id = 2, Name = "Meissel"},
                new Product {Id = 3, Name = "Magel"},
                new Product {Id = 4, Name = "Schraube"},
                new Product {Id = 5, Name = "Leim"}
            };

            var sales = new[]
            {
                new Sale {Id=10, Name="Siggi", IsValid = true, ProductId = 1 },
                new Sale {Id=12, Name="Franz", IsValid = true, ProductId = 2 },
                new Sale {Id=13, Name="Bernd", IsValid = false, ProductId = 3 }
            };

            var baseDate = new DateTime(2015, 1, 25);
            var validSales = from sale in sales
                join product in products on sale.ProductId equals product.Id
                where sale.IsValid && product.IsActive && (product.DeleteDate - baseDate).Days >= 0
                select sale;

            foreach (var sale in validSales)
                Console.WriteLine(sale.Id + " " + sale.Name + " " + sale.ProductId + " " + sale.IsValid);

Gibt die von dir gewünschte Ausgabe.

Du willst da einen join verwenden da du das Kreuzprodukt aus Produkt und Verkauf willst und zwar sollen die beiden Tabellen anhand der Bedingung Verkauf.ProductId = Product.Id verknüpft werden. Anschliessend wählst du auf diesem Kreuzprodukt diejenigen Zeilen aus, die deine Bedingungen erfüllen.

Viele Grüsse
Cromon
 

julia23

Mitglied
Vielen Dank schon mal für die Antwort das hat mich sehr weiter gebracht.

Ich habe dazu aber noch eine weiterführende Frage.

In meinem Code befinden sich nun mehrere solche abfragen, die Teilweise das Gleiche enthalten.
Somit habe ich Code ausgelagert, hier mal unserem Beispiel nachempfunden:

class QuereyString()
{
public string validsales= "join product in products on sale.ProductId equals product.Id where sale.IsValid";
public string ValidSales() {return validsales;}
}

class Programm()
{
var validSalesActive = from sale in sales +
ValidSales()
&& product.IsActive
select sale;

var validSales = from sale in sales
join product in products on sale.ProductId equals product.Id
&& product.IsActive && (product.DeleteDate - baseDate).Days >= 0
select sale;
 

julia23

Mitglied
Ist das überhaupt so möglich? Momentan zeigt er mir immer einen Semantik fehler an, egal wie ich es hindrehe.
Evtl bin ich ja total auf dem Holzweg...