poniedziałek, 19 marca 2012

Entity Framework - generowany SQL przez LINQ oraz operator IN w LINQ

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:
  1. Definiuje tablicę z wartościami które mają trafić do zapytania
  2. 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)

Brak komentarzy:

Prześlij komentarz