블로그 이미지
따시쿵

calendar

1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

Notice

2015. 8. 11. 11:39 C# with LINQ to SQL

 lazy loading의 쿼리 횟수는 Categories 데이타의 N + 1 select 를 수행합니다.

 

위의 예제에서는 두 테이블간에 one-to-many 의 관계로 이루어져 있으며, Categories 데이타는 하나 혹은 그 이상의 Products 테이타를 가지고 있습니다. 

 

Categories 테이블에는 8개의 데이타가 있으며, Products 테이블에는 77개의 데이타가 있습니다.

 

모든 Categories 테이블의 데이타를 반복적으로 추출하기 위해서는 foreach 문을 이용해서 Categories 테이블을 스캔합니다. 모든 Products 의 리스트를 출력하기 위해서는 LINQ to SQL 에서는 기본적으로 다음의 구문을 따릅니다.

 

select * from Categories

/* For each Categories */

select * from Products where CategoriesID = x

 

 

이것이 의미하는 것은, Categories 테이블에 대해 한 번의 select 문이 수행하고, Products 테이블에 대해 N 번의 select 문 수행이 이루어진다는 것입니다. 여기서 N 은 Categories 테이블의 데이타 개수입니다. 따라서 총 select 실행 횟수는 N + 1 입니다.

 

시스템의 구조나 쿼리문이 적용되는 곳이 어디냐에 따라 두 가지 모두 적재적소에 사용하면 되는 것이지만, eager loading 을 이용하면 한 번의 쿼리문으로 모든 데이타를 추출 할 수 있으며 어플리케이션 성능 향상을 위해서 cache 기능을 적절히 이용하여 사용 할 수 있습니다.

 

 

lazy loading 을 이용할 때의, 쿼리 프로파일러를 이용해서 화면을 캡쳐한 내용입니다. 

 

 

 

posted by 따시쿵
2015. 8. 10. 16:21 C# with LINQ to SQL

Eager loading?


질문의 문 안에서 쿼리문이 동시에 실행되어 데이타를 가져오는 절차입니다.


예제는 앞 포스팅에서 있는 예제(lazy loading) 를 변경하는 것으로 하겠습니다.


1. Eager loading 을 구현하는 방법 

  • DataLoadOption 을 이용해서
  • Projection 을 이용해서

  



2-1. DataLoadOptions 를 이용하는 방법


Program.cs 파일을 열어서 System.Data.Linq 네임 스페이스를 추가하고, 다음의 코드를 dbContext.Log = Console.Out; 다음에 삽입합니다.

                DataLoadOptions loadOptions = new DataLoadOptions();
                loadOptions.LoadWith<categories>(d => d.Products);
                dbContext.LoadOptions = loadOptions;

전체적인 코드를 아래와 같습니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Linq;

namespace MyLINQ11
{
    class Program
    {
        static void Main(string[] args)
        {
            using (NorhwindDBDataContext dbContext = new NorhwindDBDataContext())
            {
                dbContext.Log = Console.Out;

                DataLoadOptions loadOptions = new DataLoadOptions();
                loadOptions.LoadWith<categories>(d => d.Products);
                dbContext.LoadOptions = loadOptions;

                foreach (Categories categories in dbContext.Categories)
                {
                    Console.WriteLine("Category Name = {0}",categories.CategoryName);
                    foreach (Products products in categories.Products)
                    {
                        Console.WriteLine("\t" + products.ProductName);                        
                    }
                    Console.WriteLine();
                }
            }

            Console.ReadKey();
        }
    }
}



2-2. Projection 를 이용하는 방법


Program.cs 파일을 열어서 다음의 코드를 dbContext.Log = Console.Out; 다음에 삽입합니다.

        var linqQuery = from categories in dbContext.Categories
                             select new { CategoryName = categories.CategoryName, Products = categories.Products };

전체적인 코드를 아래와 같습니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Linq;

namespace MyLINQ11
{
    class Program
    {
        static void Main(string[] args)
        {
            using (NorhwindDBDataContext dbContext = new NorhwindDBDataContext())
            {
                dbContext.Log = Console.Out;

                var linqQuery = from categories in dbContext.Categories
                                select new { CategoryName = categories.CategoryName, Products = categories.Products };

                foreach (var categories in linqQuery)
                {
                    Console.WriteLine("Category Name = {0}",categories.CategoryName);
                    foreach (Products products in categories.Products)
                    {
                        Console.WriteLine("\t" + products.ProductName);                        
                    }
                    Console.WriteLine();
                }
            }

            Console.ReadKey();
        }
    }
}


3. 결과 화면입니다.



결과 화면에서 보듯이, 조인 쿼리를 한다는 것입니다. 

그래서 앞의 lazy loading 시와 비교해서 Categories 테이블의 테이타가 루프를 돌면서 하나씩 데이타를 가져와서 관련된 Products 테이블의 해당하는 제품을 가져오는 반면에, eager loading 은 Categories 테이블과 Products 테이블을 조인해서 한번에 데이타를 가져오는 방법입니다.


소스 파일 : 

MyLINQ11.zip



posted by 따시쿵
2015. 8. 7. 16:05 C# with LINQ to SQL

Lazy loading?


실제적으로 데이타를 액세스하는 시점은 반복적으로 데이블이나 엔터터의 데이타를 변수에 바인딩하는 시점입니다. 테이블이나 엔터티를 매핑하는 시점이 아니라는 것입니다. 기본적으로 LINQ는 Lazy loading 기법을 사용합니다.



Categories, Products 테이블 사이에는 one-to many 관계를 형성합니다.


Categories 는 하나 또는 그 이상의 Products 을 가지고 있습니다. Categories 테이블이 메모리로 loading 될 때에 Products 테이블은 load 되지 않습니다. Products 테이블이 메모리로 로드되는 시점은 특정 Categories 테이블에 해당하는, 즉 조건에 맞는 Products 테이블의 테이타를 반복적으로 찾을 때입니다.


1. Console Application 을 생성합니다.


실행시 결과 화면입니다.


2. [추가] => [새항목] => [LINQ to SQL 클래스] 선택, 이름은 NorhwindDB.dbml 로 입력합니다.

그리고, Categories, Products 테이블을 선택해서 끌어다 놓습니다.([서버 탐색기] 에 데이타베이스가 연결되어 있어야 합니다.). 최종 화면은 맨 위에 있는 그림과 같이 one-to-many 관계로 연결되어 있습니다.


3. Program.cs 파일의 Main 함수를 다음과 같이 변경합니다.

        static void Main(string[] args)
        {
            using (NorhwindDBDataContext dbContext = new NorhwindDBDataContext())
            {
                dbContext.Log = Console.Out;
                foreach (Categories categories in dbContext.Categories)
                {
                    Console.WriteLine("Category Name = {0}",categories.CategoryName);
                    foreach (Products products in categories.Products)
                    {
                        Console.WriteLine("\t" + products.ProductName);                        
                    }
                    Console.WriteLine();
                }
            }

            Console.ReadKey();
        }


소스 파일 : 

MyLINQ11.zip


posted by 따시쿵