이제 본격적으로 시작해 보죠.

앞의 내용들을 다 하고 나면
LINQ to SQL 클래스 만들때 넣은 이름+Context라는 클래스를 사용할수 있어요.

먼저 간단한 select부터 해볼께요.


             using (DataClasses1DataContext db = new DataClasses1DataContext())
            {
                var r01 = from x in db.LINQTEST
                          where x.age > 20
                          select x;

                foreach (var x in r01)
                {
                    Console.WriteLine(x.name);
                }
            }

LINQ to SQL 클래스를 쓰는거 말고는
전에 했던 LINQ to Object와 별 차이가 없네요

위 코드는
LINQTEST 테이블에서 age가 20보다 큰 x를 가져와서
x의 name을 출력하는 거에요.

이렇게 나오네요.

뭐. 설명하고 자시고 할것도 없네요.

이번에는 insert를 해볼께요.
먼저 코드
            using (DataClasses1DataContext db = new DataClasses1DataContext())
            {
                //객체를 만듭니다
                LINQTEST newData = new LINQTEST();
                //데이터를 넣습니다
                newData.name = "피요히코";
                newData.age = 30;
                newData.comment = "추가된 데이터입니다.";
                //변경된 내용을 반영합니다.
                db.LINQTEST.InsertOnSubmit(newData);
                db.SubmitChanges();
            }

순서는
1. insert할 객체를 만들고
2. 데이터를 넣고
3. 적용시킨다

입니다.

주의해야 할건
1. 테이블에는 항상 기본키가 잡혀 있어야 한다.
2. 변경내용은 SubmitChanges()를 해야 적용된다.
입니다.

LINQ to SQL 클래스를 사용하면 인텔리센스를 통해서 table과 column등에 접근할수 있으므로
정말 편하게 쿼리를 날릴수 있어요.

코드 자체는 어렵지 않으니
update와 delete 하는건 코드만 보고 넘어가도 될꺼 같네요.
(몇몇 중요해 보이는 부분은 주석으로 설명을 해둘꼐요)

update

            using (DataClasses1DataContext db = new DataClasses1DataContext())
            {
                var searchItem = (from x in db.LINQTEST
                                  where x.name == "피요히코"
                                  select x).SingleOrDefault();
                //Single()로 검색할경우 해당값이 없으면 Exception발생
                //SingleOrDefault()의 경우는 값 없을때 Null 리턴

                if (searchItem != null)
                {
                    //searchItem이 null이 아닌경우 comment를 변경
                    searchItem.comment = "변경되었어요.....";
                }

                //변경내용 확인
                var r01 = (from x in db.LINQTEST
                           where x.name == "피요히코"
                           select x).SingleOrDefault();
                Console.WriteLine(r01.comment);
            }

delete
            using (DataClasses1DataContext db = new DataClasses1DataContext())
            {
               var searchItem = (from x in db.LINQTEST
                                  where x.name == "피요히코"
                                  select x).SingleOrDefault();

                //삭제
                db.LINQTEST.DeleteOnSubmit(searchItem);
                db.SubmitChanges();

                //결과확인
                var searchItem2 = (from x in db.LINQTEST
                                  where x.name == "피요히코"
                                  select x).SingleOrDefault();
                if (searchItem2 == null)
                {
                    Console.WriteLine("지워졌다. ㅠㅠ");
                }
                else
                    Console.WriteLine(searchItem2.name);
            }

출처?는 김수영MVP님의 주말특강입니다
by 피요히코~ 2009. 4. 26. 21:05

이번에는 (좀더 많이 쓸수 있어 보이는)
LINQ to ADO.NET에 대해 봐볼께요
(LINQ to SQL이라고 해도 될듯한..)

이녀석은 일단 몇가지 선행작업이 필요해요.

일단 test해볼 테이블을 하나 만들었습니다.



그리고 테이블에 간단한 데이터를 몇개 넣어놨어요.


데이터가 뭐 이러냐 싶겠지만 pass....

비주얼스튜디오에서 서버탐색기를 열어서
DB를 연결시켜 줍니다.


그다음에
새항목을 추가 해야 되는데요.
LINQ to SQL 클래스를 추가해 줘야 해요.
이름은 MS에서 추천해주는 이름으로~

그러면
DataClasses1.dbml 파일과 DataClasses1.designer.cs 파일이 생겨요.
그리고 DataClasses1.dbml이 열려 있는데.
그 화면에
쓰고 싶은 테이블이나 프로시저 등을 서버탐색기에서 끌어다 놓으면 됩니다.

전 아까 만들어둔 LINQTEST 테이블을 끌어다 놓을께요.
(끌어 놓을때 경고창이 하나 떠요
 연결문자열을 구성파일에 저장할꺼냐 말꺼냐.
 아니요~ 하면 됩니다
 대신 app.config에서 connectionString에 pwd를 추가해 주셔야 해요. )

여기까지 했으면 이제 준비가 끝났네요...



출처?는 김수영MVP님의 주말특강입니다
by 피요히코~ 2009. 4. 26. 20:51
LINQ to Object 마지막입니다.
(사실 내용이 Object에만 해당되는건 아니죠.. -ㅁ-;;)

이번엔 Take와 Skip,그리고 TakeWhile, SkipWhile에 대해볼께요.

예제는 너무나도 간단하네요.


            int[] nums = { 10, 9, 8, 7, 5, 6, 4, 3, 2, 1 };

            var r01 = nums.Take(3);
            var r02 = nums.Skip(3);
            var r03 = nums.TakeWhile(x => x > 5);
            var r04 = nums.SkipWhile(x => x > 5);

간단하지만 (저는)헷깔릴수 있으니 잘 봐야 합니다. ㅋ
일단 nums를 보면 숫자 순서가 7,6,5 가 아니라 7,5,6 입니다.

첫번째로 Take(3)을 하면 그냥 앞에서 3개만 가져옵니다.
두번째로 Skip(3)을 하면 반대로 뒤에서 3개만 가져오죠

While이 좀 헷깔리는데요
r03에서 TakeWhile(x => x > 5)를 하면
x가 5보가 큰 녀석들을 가져오는건데.
이게 (루프를 돌겠죠?) 5보다 큰녀석을 다 가져오는게 아닙니다.
10,9,8,~~ 돌면서 5보다 큰 녀석을 찾는데
보면.. 7 까지는 5보다 크지만 그 다음에 5는 5보다 크지 않죠.
그럼 거기서 끝납니다.
그 다음에 6이라는 숫자가 5보다 크지만.
신경 안써요.
그냥 끝나버리는거에요.

SkipWhile도 비슷해요.
5보다 크면 skip해버리는데
10~7까지 스킵하고. 5부터 출력을 하는데. 그 다음수인 6이 5보다 큰거 따위 신경 안쓰죠.


그럼 이번에는
Non-Generic 타입을 사용하는걸 봐볼께요.
Non-Generic 타입은 바로 사용은 못합니다.

코드를 보면
일단 ArrayList를 선언하고 값을 몇개 넣습니다.
            ArrayList src = new ArrayList();
            for (int i = 0; i < 10; i++)
            {
                src.Add(i + 1);
            }

그 다음에
                      var r01 = from x in src
                      where x > 3
                      select x;


이렇게 해주면 바로 오류가 납니다.
오류 내용은

소스형식 'System.Collections.ArrayList'에 대해 구현된 쿼리 패턴을 찾을 수 없습니다.
'Where'을(를) 찾지 못했습니다. 범위 변수 'x'의 형식을 명시적으로 지정하십시오.

라고 나오네요
ArrayList를 사용하고 싶으면
casting을 해줘야 해요

                      var r01 = from x in src.Cast()
                      where x > 3
                      select x;

요렇게요.
그럼 결과값이 잘 나옵니다.

출처?는 김수영MVP님의 주말특강입니다
by 피요히코~ 2009. 4. 26. 20:16

앞에 포스팅했던 LINQ to Object 이어서 줄줄 입니다.

이번에는 간단하게 SubQuery에 대해 볼께요.
그냥 쿼리 안에 쿼리가 있는건데
T-SQL에서도 조건에 쿼리를 붙이고 하는걸 LINQ로 하면요

           string[] names = { "Tom", "Bill", "Harry", "June", "Mary", "Jay" };

            var r01 = from x in names
                      where x.Length == (
                                          from y in names
                                          orderby y.Length
                                          select y).First().Length
                      select x;

            foreach (var x in r01)
            {
                Console.WriteLine(x);
            }

그냥.
names에서 x라는 녀석을 가져오는데

(여기부터가 subQuery죠)
(다시)
names에서 y라는 녀석을 가져오는데
y의 길이로 정렬을 해서
가져온후에
첫번째 녀석(First())의 길이를 가져온다    << 이녀석이 x의 조건이 되는거에요
(subQuery끝)

이 길이의 x를 가져온다...

가 되는거죠.
정렬에 따로 말이 없으면 ascending이므로
Tom인지  Jay인지는 모르겠지만 암튼 둘중 하나가 First가 되겠죠.
그녀석의 길이와 같은 x를 가져오는것이니

출력값은????
이렇게 나오네요.

이번엔 into에 대해 살펴보죠(헥헥헥)
into키워드는 group, join, select 같은 임시 저장 식별자를 만들어 주는건데요.

예제를 보는게 이해가 빠를꺼에요.

                      var r01 = from x in names
                      where x.Contains("a")
                      select x
                          into subSet
                          where subSet.Length > 4
                          orderby subSet
                          select subSet;


(제가 이해한게 맞다면)
into는 (단어 뜻 그대로)
into키워드 앞의 결과를 뒤에 넣어주는거죠
코드를 보면
x를 subSet에 into했네요.
그 다음에 subSet을 가지고
조건을 걸어서(정렬조건도)
select~

그럼 결과는 어떻게 나올까요?
이름에 "a"가 들어간 놈을 찾아서 나온 결과들중에서(이게 x)
길이가 4 이상인 녀석들을 select하니까.

이렇게 나오네요.
(아마도 x에는 Harry랑 Mary랑 Jay가 있었겠죠)

into를 쓸때 주의할껀
into를 쓴 후에는
원본 x에 접근을 할수가 없다는 거에요.

원본 x에도 접근하고 싶다면
into가 아니라 let을 쓰면 되요
let키워드는 부분결과 집합을 만들어서 쿼리내에서 참조 하는겁니다

                      var r01 = from x in names
                      let temp = x.Replace("a", "")
                      where x.Contains("a")
                      select new
                      {
                          Original = x,
                          Change = temp
                      };

출력값은

간단하네요~

출처?는 김수영MVP님의 주말특강입니다
by 피요히코~ 2009. 4. 26. 19:49

LINQ to Object는

IEnumerable<T> interface가 구현된 어떤 Object에서도 사용이 가능합니다.

Non-Generic 타임은 Cast를 통해 쿼리가 가능합니다.

예제를 보죠.

private static void QuetyTest()
{
     string[] names = { "Tom", "Bill", "Harry", "June", "Mary", "Jay" };

     var r01 = from x in names
          where x.Contains("a")
          orderby x.Length
          select x;

     foreach (var x in r01)
     {
          Console.WriteLine(x);
      }
}

형식은 sql을 해봤다면 눈에 살짝 들어올꺼에요.
3번째 줄에서는 사용할 data를 만들었어요(이름들이죠)

5번째 줄~8번째줄에서 data를 가져오는데요
names는 사용할data
x는 그 data에서 한녀석(?)을 의미해요.
(위의 names에 있는 이름들 하나하나 같은거죠.... 음....)

where 뒤쪽이 이제 가져올 data에 대한 조건을 의미하고
Contains("a")는 "a"가 포함되어 있는지 여부를 확인하는 겁니다.

orderby 는 정렬조건인데
orderby x.Length는 x의 길이로 정렬을 한다는 거죠(참 쉽죠잉~  )

이렇게 하면 r01에 해당 data가 들어가 있겠죠.

그 다음에 출력을 해보면
이렇게 나와요.
(이름에 "a"가 들어가 있는 녀석들만 나오는거죠.)

그럼 이제
앞에 포스팅 했던 글에서 말했던
지연실행에 대해 볼께요.

            var numbers = new List();
            numbers.Add(1);

            var r01 = numbers.Select(x => x * 10);

            numbers.Add(2);

            foreach (var x in r01)
            {
                Console.WriteLine(x);
            }

2번째 줄에서 numbers에 1을 넣고.
3번째 줄에서 numbers.select를 해서 값을 가져옵니다.
가져올 값 x는 x*10을 해서요

그러면 r01에는 10이 들어가겠죠?

그 다음에 numbers에 2를 넣어줍니다.

그리고 출력을 합니다.

결과가 어떻게 나올까요?
10 이 나와야 할꺼 같네요.

근데 10과 20이 출력 됐네요...

10과 20이 출력된 이유는 바로
LINQ가 지연실행되기 때문입니다.
1을 넣고 r01에 1*10을 넣었지만.

그때 쿼리가 실행된게 아니라 데이터가 열거되는 시점인
5번째줄~8번째 줄때 쿼리가 실행됐기 때문에
numbers.Add(2)가 포함된 값이 출력된것이죠.

이걸 잘 염두해 두지 않으면
정말로 원치 않는 엉뚱한 결과가 나올수도 있어요.

하지만 (역시 앞에서 말했던 건데요)
이걸 바로 실행되게 할수도 있어요

var r01 = numbers.Select(x => x * 10).ToList();

이렇게 해주면
바로 쿼리가 실행되서
원하는(이걸 원한다면 말이죠) 값이 출력 되겠죠.

글이 너무 길어지면 보기 싫으니
나머지 예제들은 뒤로 보낼께요

출처?는 김수영MVP님의 주말특강입니다
by 피요히코~ 2009. 4. 26. 19:28

먼저 주요 연산자를 살펴볼께요.

(출처는 김수영님의 주말특강 PPT자료입니다.... )

연산자들이 딱 보면 대충 뭐에 쓰는지 다 감이  오네요.
이 연산자들은
LINQ to Object이건 XML이건 다 적용이 됩니다. 

예제는 다음 LINQ to Object에서 보여드릴께요

LINQ를 사용할때.
꼭 염두해둬야 할께 있는데요
LINQ는 지연실행(Deferred Execution) 된다는 겁니다.

생성시에 쿼리가 실행되는게 아니라 데이터가 열거될때 실행된다는 건데요
이게 왜 중요한지는 뒤의 예제에서 같이 보여드릴꼐요.

단 예외적으로 지연실행 되지 않는 경우가 있는데
- First, Count같은 스칼라 값이나 단일 element를 반환할때
- ToArray, ToList, ToDictionary, ToLookup 실행때 입니다.
(원본 데이터를 처리하는게 아니라. Copy를 할때)

출처?는 김수영MVP님의 주말특강입니다
by 피요히코~ 2009. 4. 26. 19:20
LINQ란 무엇인지 먼저
MSDN의 설명을 간단하게 보면요

업데이트: 2007년 11월

LINQ(통합 언어 쿼리)는 개체와 데이터 간 격차를 줄이므로 Visual Studio 2008 및 .NET Framework 버전 3.5에서 획기적인 혁신입니다.

일반적으로 데이터에 대한 쿼리는 컴파일 시 형식 검사 또는 IntelliSense 지원 없이 단순 문자열로 표현됩니다. 게다가 각 데이터 소스 형식에 대해 SQL 데이터베이스, XML 문서, 다양한 웹 서비스 등 다양한 쿼리 언어를 배워야 합니다. LINQ는 C# 및 Visual Basic에서 쿼리를 고급 언어 구문으로 만듭니다. 언어 키워드 및 친숙한 연산자를 사용하여 개체에 대한 강력한 형식의 컬렉션에 대해 쿼리를 작성합니다. 다음 그림에서는 전체 형식 검사 및 IntelliSense 지원을 사용하여 C#에서 SQL Server 데이터베이스에 대해 부분적으로 완료된 LINQ 쿼리를 보여 줍니다.

Intellisense를 사용한 LINQ 쿼리

Visual Studio에서는 Visual Basic 또는 C#을 사용하여 SQL Server 데이터베이스, XML 문서, ADO.NET 데이터 집합 및 IEnumerable 또는 제네릭 IEnumerable<(Of <(T>)>) 인터페이스를 지원하는 개체의 컬렉션에 대한 LINQ 쿼리를 작성할 수 있습니다. ADO.NET Entity Framework에 대한 LINQ 지원도 계획되어 있으며 여러 웹 서비스 및 다른 데이터베이스 구현에 대한 LINQ 공급자도 타사에 의해 개발되고 있습니다.

새 프로젝트의 LINQ 쿼리나 기존 프로젝트의 LINQ가 아닌 쿼리를 함께 사용할 수 있습니다. 단, 프로젝트에서 .NET Framework 버전 3.5를 대상으로 해야 합니다.

(출처 : MSDN)

이렇게 되어 있네요.
LINQ는 Language 레벨에서 통합된 질의(Query)를 가능케 하는 문법(?) 이라고 하면 되지 않을까 싶어요
(제가 이렇게 알고 있거든요. --ㅋ)

LINQ를 사용하면
코드에서 오류등을 표시해 주기 때문에 오류를 줄일수 있어요.
(그냥 쌩으로 쿼리를 날리면 string으로 넘어가니. 작성 시점에서 이제 맞게 작성 됐는지 알기가 힘들잖아요.
 물론 미리 한번 확인을 해보고 쓰면 되긴 하겠지만요. ㅎㅎ)

LINQ는
LINQ to Object
LINQ to DataSets
LINQ to SQL
LINQ to Entities
LINQ to XML

이 있는데

저는 Object와 DataSet, SQL, XML에 대해 정리해 볼께요.
by 피요히코~ 2009. 4. 26. 19:13
확장메소드에 대해 써볼께요.
MSDN에는 이렇게 나와있다고 하네요

확장 메서드는 형식으 ㅣ인스턴스 메서드인 것처럼 호출할수 있도록 형식과 연결된 수 있는
정적 메서드 입니다.
이 기능을 사용하면 실제로 기존 형식을 수정하지 않고도 기존 형ㅅ익에 새 메서드를 추가할수 있습니다.

Javascript에서도 이런 기능이 있죠.(Prototype)

C#에서는 IEnumerable<T> interface가 구현된 모든 타입에서 구현이 가능합니다.

간단한 소스를 봐보면요
    public static class MyExtensions
    {
        public static int wordCount(this string str)
        {
            return str.Length;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            string s = "Extension Methods";
            Console.WriteLine(s.wordCount().ToString());
        }
    }

 

확장메서드의 가장 큰 장점(?) 은 원래 부터 정의되어 있는 메서드 처럼 사용할수 있다는거죠.
실제로 String에는 wordCount() 라는 메서드가 없잖아요.
근데 그냥 . 찍고 wordCount() 해주면 새로 정의한 메서드가 호출되는거죠.
(사용자가 사용하기가 참 편하겠죠)
차이가 있다면 인텔리센스에서 메서드표시 옆에 화살표가 표시되는것과
이름옆에 (확장)이라고 표시되는거죠.



라인1 부터 7 까지가 확장메서드 입니다.
간단하게 string값의 길이(length)를 반환하는 메서드를 작성했어요(출력값은 17 이에요)

MyExtentions 라는 정적 클래스를 선언하고 그 안에 wordCount라는 메서드를 선언했어요.
인수는 string 객체이며 this 키워드를 붙입니다.
여기서 this는 호출객체를 의미하는 참조자가 아니라 뒤의 클래스에 대한 확장메서드임을 의미하는
지정자에요.  wordCount가 string의 확장메서드라는 의미죠.

코드에서는 인수를 한개만 받았지만 실제로 인수는 제한이 없습니다.
두번째 인수부터는 실제 연산에 필요한 값들을 받으면 되는거죠.

(아무 의미가 없지만. --)string의 length에 특정 숫자를 붙인 int를 받는 메서드를 작성하고 싶으면


     public static class MyExtensions
    {
        public static int wordCount(this string str, int add)
        {
            return str.Length+add;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            string s = "Extension Methods";
            Console.WriteLine(s.wordCount(5).ToString());
        }
    }


이렇게 해주면 되죠.(출력값은 17+5 해서 22가 나오겠죠?)

확장메서드는 인스턴스 메서드처럼 사용되지만 소속은 분명히 클래스 외부입니다.
그러므로(당연히) 확장하는 클래스의 숨겨진 멤버들에는 접근을 할수가 없어요.
그래서 확장 메서드로 클래스를 확장한다고 캡슐화를 위한바는것도 아니고.
보안상으로도 별 문제가 없다고 하네요.

by 피요히코~ 2009. 4. 26. 18:45
이번엔 익명형식이라는 녀석에 대해 알아볼께요.

익명형식은 이렇게 사용해요.

var anonyValue = new {Name = "피요히코", Age=30 };

아주 간단하죠?
이렇게 하면 내부적으로
이렇게 바꿔준다네요


internal class???
{
     string _Name;
     int _Age;
     public string Name
     {
          get{return _Name;} set {_Name = value;}
     }
     public int Age
     {
          get{return _Age;} set{_Age = value;}
     }
}

알아서 해주는거죠.
대신 이렇게 알아서 하기 위해서
compile시에는 느려지게 됩니다.
(complie때 알아서 알아서 하려면 어쩔수 었겠죠)

대신 컴파일 되고 나서는 성능에 대한 문제는 없다네요

이런 익명형식은
- 이름을 컨트롤 할수가 없어요. (complie시에 알아서 알아서)
- 항상 System.Object를 확장해요
- 필드와 프로퍼티는 항상 read-only에요
- 이벤트나 커스텀메소드등을 지원안해요.
- 항상 묵시적으로 selead에요(상속같은건 못해요)
- 항상 기본생성자를 사용해서 생성되요.


출처?는 김수영MVP님의 주말특강입니다
by 피요히코~ 2009. 4. 26. 13:56

토요일에 있었던 김수영MVP님의 교육을 다녀온 후에
좋은 내용을 너무 많이 듣고 와서
정리의 필요성을 느끼고 정리합니다. ㅋ
(수영님 다시한번 감사~ )

C# 3.0에서 새로 생긴 타입(?) 인 var는 Javascript에서 많이 보던 녀석이죠.
int나 string처럼 변수에 들어가는 녀석들의 종류가 미리 명시되는게 아니라
변수에 값이 대입되고 나서야 타입이 정해지는(맞죠? ;;;)
여러면서에 C#의 Object타입과도 비슷하지만.
다른녀석이죠

C#의 Object와 비교해 본다면
Object타입은 .NET에서의 모든 자료형은 Object를 상속받기 때문에
어떤형식도 Object에 넣을수는 있지만. Object는 타입을 추정할수가 없지요

예를들어서 제가

object objType = "초기화";
var varType = "초기화";

이런 코드를 작성했다고 할때

이 변수를 가지고 뭔가를 하려고 할때 . 을 찍어보면 차이가 확 나타나요




var 타입의 경우는
'이녀석이 string이구만~ ' 이라고 타입을 추정해서 인텔리센스세 string이 지원하는 메소드등등이 줄줄 보이는데요
object의 경우는 그렇지 않죠.
아주아주아주 기본적인 (이게 Object형식이면 모두 지원되는 메소드 겠죠?) 메소드 딸랑 4개만 보이네요.

또 다른 차이는
var타입의 경우는 Compile 때 타입을 검사하고 Object는 Runtime시에 검사를 한다는 겁니다.
이말은
var타입의 경우는 compile시에 타입이 확정되기 때문에
불필요한 boxing 이나 unboxing등이 생기지 않는다는거죠
compile때 이미
'이녀석은 int구나..'
혹은
'이녀석은 string이구나' 등이 정해지니
그럴일이 없겠죠.

또한 compile시에 타입을 검사하고 확정하기 떄문에 타입이 변경될수 없어요.
처음에 var타입에 숫자를 넣었다면 앞으로 그 변수에는 숫자만 넣어야 한다는거죠.

출처?는 김수영MVP님의 주말특강입니다
by 피요히코~ 2009. 4. 26. 13:42
| 1 2 3 4 5 6 7 8 ··· 12 |