Dziś krótko o dwóch przydatnych czynnościach, z którymi możemy się zmierzyć w przypadku EF + LINQ.
1. Pobieranie SQL-a generowanego przez LINQ
Pracując z EF nie wiele zwraca się uwagi na generowane zapytania przez ORM. Warto jednak niekiedy podglądnąć w jaki sposób jest generowane zapytanie do bazy. Sposób który podam może także przydać się w przypadku kiedy chcemy przeprowadzić optymalizację zapytań. Aby zobaczyć wygenerowane zapytanie do bazy należy skorzystać z poniższego kodu:
Code:
using System;
using System.Data.Objects;
using System.Linq;
namespace ConsoleApplication11
{
class Program
{
static void Main()
{
using (var contex = new AdventureWorksLT2008R2Entities())
{
var customer = from c in contex.Customers
join soh in contex.SalesOrderHeaders on c.CustomerID equals soh.CustomerID
join sod in contex.SalesOrderDetails on soh.SalesOrderID equals sod.SalesOrderID
join p in contex.Products on sod.ProductID equals p.ProductID
where c.CustomerID == 30113
select p;
Console.WriteLine(((ObjectQuery) customer).ToTraceString());
}
}
}
}
W wyniku wywołania otrzymamy następujący wynik:
Otrzymany wynik możemy bez przeszkód przekleić do ManagementStudio i wywołać.
2. Operator IN w LINQ
Przez dłuższy czas szukałem sposoby w jaki generować za pomocą LINQ zapytania do bazy z użyciem operatora IN. W końcu po przegrzebaniu internetu znalazłem prostą odpowiedź:
Code:
using System;
using System.Data.Objects;
using System.Linq;
namespace ConsoleApplication11
{
class Program
{
static void Main()
{
using (var contex = new AdventureWorksLT2008R2Entities())
{
int[] customerIds = {30046, 30047, 30048, 30050, 30051, 30052};
var customer = from c in contex.Customers
join soh in contex.SalesOrderHeaders on c.CustomerID equals soh.CustomerID
join sod in contex.SalesOrderDetails on soh.SalesOrderID equals sod.SalesOrderID
join p in contex.Products on sod.ProductID equals p.ProductID
where customerIds.Contains(c.CustomerID)
select p;
string sql = ((ObjectQuery) customer).ToTraceString();
Console.WriteLine(sql);
}
}
}
}
Tak więc:
- Definiuje tablicę z wartościami które mają trafić do zapytania
- W zapytaniu sprawdzam w tablicy czy nie zawiera wartości z bazy danych
W wyniku tego zapytania otrzymuję to co chciałem czyli operator IN:
SELECT
[Extent3].[ProductID] AS [ProductID],
[Extent3].[Name] AS [Name],
[Extent3].[ProductNumber] AS [ProductNumber],
[Extent3].[Color] AS [Color],
[Extent3].[StandardCost] AS [StandardCost],
[Extent3].[ListPrice] AS [ListPrice],
[Extent3].[Size] AS [Size],
[Extent3].[Weight] AS [Weight],
[Extent3].[ProductCategoryID] AS [ProductCategoryID],
[Extent3].[ProductModelID] AS [ProductModelID],
[Extent3].[SellStartDate] AS [SellStartDate],
[Extent3].[SellEndDate] AS [SellEndDate],
[Extent3].[DiscontinuedDate] AS [DiscontinuedDate],
[Extent3].[ThumbNailPhoto] AS [ThumbNailPhoto],
[Extent3].[ThumbnailPhotoFileName] AS [ThumbnailPhotoFileName],
[Extent3].[rowguid] AS [rowguid],
[Extent3].[ModifiedDate] AS [ModifiedDate]
FROM [SalesLT].[SalesOrderHeader] AS [Extent1]
INNER JOIN [SalesLT].[SalesOrderDetail] AS [Extent2] ON [Extent1].[SalesOrderID] = [Extent2].[SalesOrderID]
INNER JOIN [SalesLT].[Product] AS [Extent3] ON [Extent2].[ProductID] = [Extent3].[ProductID]
WHERE [Extent1].[CustomerID] IN (30046,30047,30048,30050,30051,30052)