2015-03-10 8 views
7

Mam bazę danych, która zawiera 3 tabele:LINQ: Czy istnieje sposób na połączenie tych zapytań w jeden?

  • Telefony
  • PhoneListings
  • PhoneConditions

PhoneListings ma FK z tabeli komórkowe (phoneid) i FK z telefonu Tabela warunków (conditionID)

Pracuję nad funkcją, która dodaje do spisu telefonów spis telefonów i zwraca wszystkie niezbędne informacje rmacja dla użytkownika. Model telefonu i model są zawarte w tabeli PHONES, a szczegóły dotyczące warunku znajdują się w tabeli PhoneConditions.

Aktualnie używam 3 zapytań, aby uzyskać wszystkie niezbędne informacje. Czy istnieje sposób, aby połączyć to wszystko w jedno zapytanie?

public ActionResult phoneAdd(int listingID, int qty) 
{ 

    ShoppingBasket myBasket = new ShoppingBasket(); 
    string BasketID = myBasket.GetBasketID(this.HttpContext); 



    var PhoneListingQuery = (from x in myDB.phoneListings 
          where x.phonelistingID == listingID 
          select x).Single(); 

    var PhoneCondition = myDB.phoneConditions 
          .Where(x => x.conditionID == PhoneListingQuery.phonelistingID).Single(); 

    var PhoneDataQuery = (from ph in myDB.Phones 
          where ph.PhoneID == PhoneListingQuery.phonePageID 
          select ph).SingleOrDefault(); 

} 
+0

jakie jest twoje uzasadnienie dla łączenia? –

+0

Po prostu mogę uzyskać wszystkie potrzebne informacje z jednego obiektu, zamiast odnosić się do trzech różnych obiektów. Może być przesada, ale myślę, że nauka tego, jak to zrobić, byłaby opłacalna. – user1698144

+0

Możesz również użyć sprzężenia https://msdn.microsoft.com/en-us/library/vstudio/bb534675(v=vs.100).aspx – Peyman

Odpowiedz

5

Można rzutować wynik do anonimowej klasy lub krotką, a nawet zwyczaj kształcie jednostka w jednej linii, jednak ogólna wydajność bazy danych nie może być lepiej:

var phoneObjects = myDB.phoneListings 
     .Where(pl => pl.phonelistingID == listingID) 
     .Select(pl => new 
     { 
      PhoneListingQuery = pl, 
      PhoneCondition = myDB.phoneConditions 
      .Single(pc => pc.conditionID == pl.phonelistingID), 
      PhoneDataQuery = myDB.Phones 
      .SingleOrDefault(ph => ph.PhoneID == pl.phonePageID) 
     }) 
     .Single(); 

    // Access phoneObjects.PhoneListingQuery/PhoneCondition/PhoneDataQuery as needed 

Występują również nieco bardziej kompaktowe przeciążenia rozszerzeń LINQ Single i SingleOrDefault, które przyjmują predykat jako parametr, który pomoże nieznacznie zmniejszyć kod.

Edit

Jako alternatywę dla wielu pobraniami z ORM DbContext lub robi wyraźne ręcznych Join s, jeśli założyć navigation relationships pomiędzy podmiotami w modelu za pośrednictwem żeglowna dołączyć klucze (zwykle kluczy obcych w tabele bazowe), można określić głębokość pobrania z upragnieniem obciążenia, przy użyciu Include:

var phoneListingWithAssociations = myDB.phoneListings 
     .Include(pl => pl.PhoneConditions) 
     .Include(pl => pl.Phones) 
     .Single(pl => pl.phonelistingID == listingID); 

Który powróci wykres podmiotem w phoneListingWithAssociations

(Zakładając, klucze obce PhoneListing.phonePageID => Phones.phoneId i PhoneCondition.conditionID => PhoneListing.phonelistingID)

2

powinien być w stanie ciągnąć to wszystko w ramach jednego zapytania z join, myślę.

Jednak, jak wskazano, możesz nie osiągnąć dużej prędkości, ponieważ właśnie wybierasz pierwszy mecz, a następnie kontynuujesz, nie robiąc żadnych wewnętrznych porównań.

Jeśli wiesz, że w każdym stole istnieje co najmniej jeden punkt danych, możesz również ciągnąć wszystko w tym samym czasie. jeśli nie, to czekanie z "sub zapytania" jest miłe, jak zrobione przez StuartLC.

var Phone = (from a in myDB.phoneListings 
     join b in myDB.phoneConditions on a.phonelistingID equals b.conditionID 
     join c in ph in myDB.Phones on a.phonePageID equals c.PhoneID 
     where 
     a.phonelistingID == listingID 
     select new { 
     Listing = a, 
     Condition = b, 
     Data = c 
     }).FirstOrDefault(); 

FirstOrDefault ponieważ błąd pojedynczego rzutu powoduje, że istnieje więcej niż jeden element.

Powiązane problemy