블로그 이미지
따시쿵

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

'c# linq'에 해당되는 글 2

  1. 2015.08.07 Lazy loading
  2. 2015.06.16 LINQ - 소개
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 따시쿵
2015. 6. 16. 10:49 C# with LINQ to SQL

LINQ 는 Language INtegrated Query위 약어로, 컬렉션을 편리하게 다루기 위한 목적으로 만들어진 질의 언어입니다. C# 3.0 버전에서부터 탑재한 LINQ 덕분에 프로그래머들은 데이타를 찾고 병합하고 정렬하는 코드를 작성하는 짐을 상당 부분 내려 놓을 수 있게 되었습니다.

 

기본 문법

 

  • From : 어떤 데이타 집합에서 찾을 것인가?
  • Where : 어떤 값의 데이타를 찾을 것인가? (필터 역할)
  • Orderby : 어떤 데이타 순서대로 나열할 것인가?(순서 정하기)
  • Select : 어떤 항목을 추출할 것인가?

 

예제 1 - LINQ 문을 사용하지 않고 프로그램 작성

 

키가 175 미만인 데이타만을 골라서 새 컬렉션으로 추출하는 프로그램

    class Profile
    {
        public string Name { get; set; }
        public int Height { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Profile[] arrProfile = {
                                       new Profile{Name = "이순신", Height=210},
                                       new Profile{Name = "강감찬", Height=169},
                                       new Profile{Name = "을지문덕", Height=175},
                                       new Profile{Name = "세종대왕", Height=183},
                                       new Profile{Name = "안창호", Height=159},
                                       new Profile{Name = "연개소문", Height=172}
                                   };

            // 1단계 - 키가 175 미만인 데이타를 추출함
            List<profile> profiles = new List<Profile>();
            foreach(Profile profile in arrProfile)
            {
                if (profile.Height < 175)
                    profiles.Add(profile);
            }

            // 2단계 - 키의 오름차순으로 정열함
            profiles.Sort(
                (profile1, profile2) =>  { return profile1.Height - profile2.Height;  }
            );

            // 3단계 - 출력함
            foreach(var profile in profiles)
                Console.WriteLine("{0}, {1}", profile.Name, profile.Height);

            Console.ReadLine();
        }
    }

 

 

예제 2 - LINQ 문을 사용하여 프로그램 작성

 

키가 175 미만인 데이타만을 골라서 새 컬렉션으로 추출하는 프로그램

    class Profile
    {
        public string Name { get; set; }
        public int Height { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Profile[] arrProfile = {
                                       new Profile{Name = "이순신", Height=210},
                                       new Profile{Name = "강감찬", Height=169},
                                       new Profile{Name = "을지문덕", Height=175},
                                       new Profile{Name = "세종대왕", Height=183},
                                       new Profile{Name = "안창호", Height=159},
                                       new Profile{Name = "연개소문", Height=172}
                                   };

            // 1단계 - 키가 175 미만인 데이타를 추출함
            var profiles = from profile in arrProfile
                           where profile.Height < 175
                           orderby profile.Height ascending
                           select profile;

            // 2단계 - 출력함
            foreach (var profile in profiles)
                Console.WriteLine("{0}, {1}", profile.Name, profile.Height);

            Console.ReadLine();
        }
    }


예제3 - select 문의 분석


select 절은 다음과 같이 사용하면 됩니다.

var profiles = from profile in arrProfile
            where profile.Height < 175
            orderby profile.Height ascending
            select profile;

위의 예에서 var 형식으로 선언된 profiles 의 실제 형식이 궁금할 겁니다. C# 컴파일러가 var 형식을 LINQ 쿼리식이 반환할 결과 형식에 맞춰 알아서 컴파일 해 주기는 하지만, 실제로 var 가 어떤 형식으로 치환되는지를 알아둘 필요가 있습니다. LINQ 질의 결과는 IEnumerable<T> 로 치환되는데, 이 형식 매개변수 T는 select 문에 의해 결정됩니다. 


예를 들어 위 LINQ 쿼리식은 배열로부터 175 미만인 Profile 객체를 골라내는데, 그 결과는 IEnumerable<Profile> 형식이 됩니다. 다음과 같이 select 문에서 Profile 객체 전체가 아닌 Name 프로퍼티만 추출하면 profiles는 IEnumerable<string> 형식으로 컴파일됩니다.

var profiles = from profile in arrProfile
            where profile.Height < 175
            orderby profile.Height ascending
            select profile.Name;

추가적으로 select 문은 무명 형식(Anonymous type)을 이용해서 다음과 같이 새로운 형식을 만들어 낼 수도 있습니다.

var profiles = from profile in arrProfile
            where profile.Height < 175
            orderby profile.Height ascending
            select new { Name = profile.Name, InchHeight = profile.Height * 0.393 };

전체 소스

    class Profile
    {
        public string Name { get; set; }
        public int Height { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Profile[] arrProfile = {
                                       new Profile{Name = "이순신", Height=210},
                                       new Profile{Name = "강감찬", Height=169},
                                       new Profile{Name = "을지문덕", Height=175},
                                       new Profile{Name = "세종대왕", Height=183},
                                       new Profile{Name = "안창호", Height=159},
                                       new Profile{Name = "연개소문", Height=172}
                                   };

            // 1단계 - 키가 175 미만인 데이타를 추출함
            var profiles = from profile in arrProfile
                           where profile.Height < 175
                           orderby profile.Height ascending
                           select new { Name = profile.Name, InchHeight = profile.Height * 0.393 };

            // 2단계 - 출력함
            foreach (var profile in profiles)
                Console.WriteLine("{0}, {1}", profile.Name, profile.InchHeight);

            Console.ReadLine();
        }
    }



 

예제4 - where 조건에 and, or 연산자 사용하기 / 여러개의 데이타 원본에 질의하기

 

LINQ 쿼리식은 데이타 원본에 접근하기 위해 from 절을 사용합니다. 여러개의 데이타 원본에 접근하려면 from 절을 중첩해서 사용하면 됩니다.

 

foreach 문을 중첩해서 사용하는 것처럼 말입니다.

 

다음의 클래스는 각 학년별, 학급별, 점수를 나타내며, 과목별 점수를 담기 위해 Score 필드를 배열로 선언했습니다.

    class GradeClassScore
    {
        public int Grade { get; set; }
        public string ClassName { get; set; }
        public int[] Score { get; set; }
    }

 

그리고 이 클래스를 바탕으로 배열 하나를 다음과 같이 선언했습니다.

            GradeClassScore[] arrClass = {
                                             new GradeClassScore(){Grade = 1, ClassName = "연두반", Score = new int[]{10, 20, 30, 40, 50}},
                                             new GradeClassScore(){Grade = 1, ClassName = "분홍반", Score = new int[]{65, 75, 85, 95, 100}},
                                             new GradeClassScore(){Grade = 1, ClassName = "파랑반", Score = new int[]{68, 28, 38, 48, 58}},
                                             new GradeClassScore(){Grade = 1, ClassName = "노랑반", Score = new int[]{83, 84, 85, 86, 86}},
                                             new GradeClassScore(){Grade = 1, ClassName = "보라반", Score = new int[]{87, 87, 87, 87, 87}},
                                             new GradeClassScore(){Grade = 2, ClassName = "연두반", Score = new int[]{10, 20, 30, 40, 50}},
                                             new GradeClassScore(){Grade = 2, ClassName = "분홍반", Score = new int[]{65, 75, 85, 95, 100}},
                                             new GradeClassScore(){Grade = 2, ClassName = "파랑반", Score = new int[]{68, 28, 38, 48, 58}},
                                             new GradeClassScore(){Grade = 2, ClassName = "노랑반", Score = new int[]{83, 84, 85, 86, 86}},
                                             new GradeClassScore(){Grade = 2, ClassName = "보라반", Score = new int[]{87, 87, 87, 87, 87}},
                                             new GradeClassScore(){Grade = 3, ClassName = "연두반", Score = new int[]{10, 20, 30, 40, 50}},
                                             new GradeClassScore(){Grade = 3, ClassName = "분홍반", Score = new int[]{65, 75, 85, 95, 100}},
                                             new GradeClassScore(){Grade = 3, ClassName = "파랑반", Score = new int[]{68, 28, 38, 48, 58}},
                                             new GradeClassScore(){Grade = 3, ClassName = "노랑반", Score = new int[]{83, 84, 85, 86, 86}},
                                             new GradeClassScore(){Grade = 3, ClassName = "보라반", Score = new int[]{87, 87, 87, 87, 87}}
                                         };

 

이제 준비는 마쳤습니다. 위 배열에서 1학년 중에서 점수가 60점 미만인 학급과 과목 점수를 중첩 from 절을 이용해서 뽑아 보겠습니다. 그리고 여기서 한가지 팁을 더 알려 드리자면 where 절에 and, or 를 포함 시킬 수 있습니다. 즉 and => &&, or => || 를 사용하시면 됩니다.

            var classes = from c in arrClass
                            from s in c.Score
                            where s < 60 && c.Grade == 1
                            orderby s
                          select new { c.ClassName, Lowest = s };

전체 소스

    class GradeClassScore
    {
        public int Grade { get; set; }
        public string ClassName { get; set; }
        public int[] Score { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            GradeClassScore[] arrClass = {
                                             new GradeClassScore(){Grade = 1, ClassName = "연두반", Score = new int[]{10, 20, 30, 40, 50}},
                                             new GradeClassScore(){Grade = 1, ClassName = "분홍반", Score = new int[]{65, 75, 85, 95, 100}},
                                             new GradeClassScore(){Grade = 1, ClassName = "파랑반", Score = new int[]{68, 28, 38, 48, 58}},
                                             new GradeClassScore(){Grade = 1, ClassName = "노랑반", Score = new int[]{83, 84, 85, 86, 86}},
                                             new GradeClassScore(){Grade = 1, ClassName = "보라반", Score = new int[]{87, 87, 87, 87, 87}},
                                             new GradeClassScore(){Grade = 2, ClassName = "연두반", Score = new int[]{10, 20, 30, 40, 50}},
                                             new GradeClassScore(){Grade = 2, ClassName = "분홍반", Score = new int[]{65, 75, 85, 95, 100}},
                                             new GradeClassScore(){Grade = 2, ClassName = "파랑반", Score = new int[]{68, 28, 38, 48, 58}},
                                             new GradeClassScore(){Grade = 2, ClassName = "노랑반", Score = new int[]{83, 84, 85, 86, 86}},
                                             new GradeClassScore(){Grade = 2, ClassName = "보라반", Score = new int[]{87, 87, 87, 87, 87}},
                                             new GradeClassScore(){Grade = 3, ClassName = "연두반", Score = new int[]{10, 20, 30, 40, 50}},
                                             new GradeClassScore(){Grade = 3, ClassName = "분홍반", Score = new int[]{65, 75, 85, 95, 100}},
                                             new GradeClassScore(){Grade = 3, ClassName = "파랑반", Score = new int[]{68, 28, 38, 48, 58}},
                                             new GradeClassScore(){Grade = 3, ClassName = "노랑반", Score = new int[]{83, 84, 85, 86, 86}},
                                             new GradeClassScore(){Grade = 3, ClassName = "보라반", Score = new int[]{87, 87, 87, 87, 87}}
                                         };

            var classes = from c in arrClass
                            from s in c.Score
                            where s < 60 && c.Grade == 1
                            orderby s
                          select new { c.ClassName, Lowest = s };

            foreach(var c in classes)
                Console.WriteLine("낙제 : {0} ({1})", c.ClassName, c.Lowest);

            Console.ReadLine();

        }
    }

 

 

posted by 따시쿵
prev 1 next