W tym artykule autor szczegółowo przedstawia zapytanie wspólne Linq, ponieważ obawiam się, że czytelnicy nie rozumieją tego aspektu zbyt dobrze, więc zanim opowiem o zapytaniu wspólnym Linq, najpierw przedstawię Ci trochę wiedzy, a następnie opowiem, jak jest implementowane zapytanie wspólne Linq, mając nadzieję, że pomogę.
Najpierw przyjrzyjmy się kilku aspektom wiedzy dotyczącej wspólnego zapytania Linq.
1. Anonimowy rodzaj dostawy
static void Main (string[] args) { var User = GetAnonymous(). Cast(new { UserName = "", LastLoginIp = "" }); Console.Write(User.UserName); } statyczny obiekt GetAnonymous() { var User = new { UserName = "yaosansi", LastLoginIp = "127.0.0.1" }; return User;
} Gdy definiujemy typ anonimowy, może on być przekazywany tylko przez typ obiektu, a kompilator nie zna rzeczywistego typu anonimowego po przekazaniu.
Linię tę można odlewać metodą Cast extension. Poniżej znajduje się prototyp metody Cast.
publiczny statyczny T Cast (ten obiekt o, T t) { return ();
} 2. Jak wygenerować anonimową listę typów dla federacyjnego zapytania Linq?
var User = GetAnonymous(). Cast(new { UserName = "", LastLoginIp = "" }); var list = nowa Lista< ?>(); Zasada jest taka sama jak powyżej.
var User = nowy { UserName = "yaosansi", LastLoginIp = "127.0.0.1" }; var list = User.MakeList(); listę. add(użytkownik); Console.write(list[0]. UserName); Przyjrzyjmy się metodzie MakeList():
public static List MakeList(this T t) { powrót nowej List();
} Oczywiście możesz uważać, że powyższa metoda nie jest wystarczająco doskonała i musisz dodać użytkownika do Listy, więc masz następującą metodę:
publiczna statyczna lista MakeList (ten T,parametry T[] pozycje) { zwróć nową listę(pozycje); } Po wywołaniu można ją zapisać jako:
var User = nowy { UserName = "yaosansi", LastLoginIp = "127.0.0.1" }; var list = User.MakeList(User); Console.write(list[0]. UserName); Tym razem przejdźmy do sedna i zrozummy, jak zaimplementowane jest federowane zapytanie Linq.
var q = z p w db. Produkty gdzie p.Supplier.Country == "USA" & p.UnitsInStock == 0 Wybierz P; Powyższe zapytanie to dwie powiązane tabele, a zwracana jest tylko zawartość jednej tabeli; w takim przypadku w warstwie danych można zwrócić silnie typowaną Listę. Na przykład:
publiczna lista SelectProducts() { var q = z p w db. Produkty gdzie p.Supplier.Country == "USA" & p.UnitsInStock == 0 Wybierz P; powrót q.ToList;
} Jeśli zwrócony zbiór wyników ma więcej niż dwie tabele, jak powinien zostać przekazany? Pewnie pomyślałeś, że jeśli zwrócony zbiór wyników to pojedyncza linia danych, możemy użyć anonimowego typu dostarczania, o którym wspomnieliśmy wcześniej, aby uzyskać potrzebne wyniki. Obiekt publiczny
obiekt publiczny SelectProducts() { var q = z p w db. Produkty gdzie p.Supplier.Country == "USA" & p.UnitsInStock == 0 wybierz nowe {p.UnitsInStock,p.Supplier.Sid}; var result = q.Single(); Zwróć wynik;
} Jednak założenie polega na tym, że warstwa logiki biznesowej musi znać konkretne typy anonimowości w warstwie danych. To warstwowanie ma niewielkie znaczenie. To nie jest to, czego chcemy. Ponadto metoda używania anonimowego typu List do zwracania zbioru wyników danych wielowierszowych również zawiodła po eksperymentach. Oznacza to, że żadna z dwóch metod zachowania anonimowości na początku tego artykułu nie zadziała.
Metoda 1: Federowane zapytanie Linq dostosowuje klasy o tej samej strukturze co typ return
klasa publiczna CustomQuery { public uint UnitsInStock { get; set; } publicznie int Sid { get; set; }
} Można to rozwiązać, gdy wyniki zapytań są zbiorem wielu tabel. Ponieważ musisz znać rodzaj anonimowości, musisz zdefiniować dodatkową klasę oprócz niezgodności z wielowarstwową. Ale to prawda i może przywrócić potrzebne rezultaty, używając silnych typów.
Metoda 2: Federowane zapytanie Linq za pomocą delegacji System.Func (Odniesienie: Zwracanie var z metody w C# 3.0)
Warstwa danych:
public IEnumerable GetCustomersWithOrders(Func, TProjection> projekcja) { zwrot od klienta w _customers niech customerOrders = z zamówienia w _orders gdzie porządek. CustomerID = customer.ID wybierz projekcję(klient, klientZamówienia);
} Warstwa logiki biznesowej:
var results = GetCustomersWithOrders( (klient, zamówienia) => nowe { Imię = klient. Imię, OrderCount = orders. Count() }); Wynik zwracany w ten sposób jest nadal prawdziwym anonimowym typem w warstwie logiki biznesowej i może być używany bezpośrednio.
Metoda 3: Zapytania federacyjne Linq wykorzystują procedury lub widoki przechowywane. |