블로그 이미지
따시쿵

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. 7. 1. 14:27 C# with LINQ to SQL

이번 포스트에서는 datagridview control 에 데이타를 select, insert, update, delete 시키는 모든 연산을 sql db 의 northwind db를 이용해서 작업해 보도록 하겠습니다.

 

일단은 sql 2012 의 norhwind db를 다음의 사이트에서 다운로드를 받아서 설치를 합니다.

http://businessimpactinc.com/install-northwind-database/

 

최종적인 결과 화면입니다.

 

1. LINQ to SQL 클래스 만들기

 

프로젝트 선택 => [추가] => [새항목] => [데이타] =>[LINQ to SQL 클래스] 선택하고 이름을 "northwind" 라 입력을 합니다.

 

그리고, 테이블을 모두 drag & drop 으로 끌어다 좌측 윈도우에 위치 시키며, 스토어 프로시저를 끌어다 오른쪽 창에 위치 시킵니다.

 

이제, northwind.dbml 파일 하단에 있는 northwind.designer.cs 파일을 열고 확인 해 보면,

맨 상단에 northwindDataContext 클래스가 있으며 하단으로 테이블명으로 되어 있는 클래스들을 확인 할 수 있습니다.

 

이번 예제에서는 Customers 테이블에 연산하는 것을 예시로 보입니다.

 

2. select

 

[Get Data] 버튼을 클릭했을 시 보이는 method, 모든 데이타를 가져옵니다.

            northwindDataContext dbContext = new northwindDataContext();

            dataGridView1.DataSource = dbContext.Customers;

 

3. insert

 

[Insert] 버튼 클릭시 작동하는 method 입니다.

            using (northwindDataContext dbContext = new northwindDataContext())
            {
                var userInfo = dbContext.Customers.Where(u => u.CustomerID == textCustomerID.Text);
                if (userInfo.Count() > 0)
                {
                    MessageBox.Show("[CustomerID] 가 중복입니다. 다른 것으로 변경하시기 바랍니다.", "에러", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    Customers customer = new Customers
                    {
                        CustomerID = textCustomerID.Text,
                        CompanyName = textCompanyName.Text,
                        ContactName = textContactName.Text,
                        ContactTitle = textContactTitle.Text,
                        Address = textAddress.Text,
                        City = textCity.Text,
                        Region = textRegion.Text,
                        PostalCode = textPostalCode.Text,
                        Country = textCountry.Text,
                        Phone = textPhone.Text,
                        Fax = textFax.Text
                    };

                    dbContext.Customers.InsertOnSubmit(customer);
                    dbContext.SubmitChanges();

                    GetData();
                }
            }

 

 

4. update

 

[Update] 버튼 클릭시 작동하는 method 입니다.

            using (northwindDataContext dbContext = new northwindDataContext())
            {
                Customers customer = dbContext.Customers.SingleOrDefault(x => x.CustomerID == textCustomerID.Text);
                customer.CompanyName = textCompanyName.Text;
                dbContext.SubmitChanges();                
            }

            GetData();

 

 

5. delete

 

[Delete] 버튼 클릭시 작동하는 method 입니다.

            using (northwindDataContext dbContext = new northwindDataContext())
            {
                try
                {
                    Customers customer = dbContext.Customers.SingleOrDefault(x => x.CustomerID == textCustomerID.Text);
                    dbContext.Customers.DeleteOnSubmit(customer);
                    dbContext.SubmitChanges();
                }
                catch(ArgumentNullException ex)
                {
                    MessageBox.Show(ex.Message, "에러", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }

            GetData();

 

 

 

전체 소스 

MyLINQ9.zip

 

posted by 따시쿵
2015. 6. 25. 14:11 C# with LINQ to SQL

이번 글에서는 LINQ와 실제 데이타베이스(MS SQL 2012)를 연결해서 데이타를 조회하는 화면을 만들어 보겠습니다.

 

시나리오는 데이타베이스에 있는 테이블에서 사용자 아이디와 비밀번호를 비교해서 같은지 다른지를 풀력하는 프로그램 입니다.

 

먼저, 결과 화면부터 보겠습니다. 성공과 실패 두가지 입니다.

 

 

 

테이블 명세서와 테이타입니다.

 

 

 

우리는 프로그램을 공부하는 사람들이니 아래 박스의 순서에 따라 작업 해 주시면 됩니다.

 

1.  프로젝트 생성하고 dbml 파일 생성하기

 

Visual Studio 2013 을 실행 시킨 다음에, 프로젝트를 Windows form 타입으로 생성을 합니다.

프로젝트는 생성 한 후, [추가] => [새항목] =>[ 데이타] =>[LINQ to SQL 클래스] 선택하고 login.dbml 파일을 만듭니다. 파일을 만들고 나면, 왼쪽 오른쪽 분할 윈도우가 나오는데 왼쪽에는 테이블을 끌어다 놓고, 오른쪽에는 사용할 스토어프로시져를 끌어다 놓습니다.

 

login.dbml 파일을 만들었으면, DataContext() 클래스에서 상속받아서 loginDataContext() 을 자동적으로 만들어 줍니다. 이 파일은 logn.designer.cs 파일을 열면 확인이 가능합니다. tbl_member class 도 같이 자동으로 만들어 줍니다.

 

loginDataContext 클래스를 이용해서 테이타 쿼리가 이루어집니다.

 

 

 

2. 로그인 버튼에 click 이벤트를 추가 합니다.

LINQ 쿼리를 사용해서 디비 테이블의 필드값을 조회하는 쿼리는 유심히 확인하시기 바랍니다.

        private void btnLogin_Click(object sender, EventArgs e)
        {
            loginDataContext myDB = new loginDataContext();

            var userResult = from u in myDB.tbl_member
                             where u.user_name == this.textUserID.Text
                             && u.user_password == this.textUserPassword.Text
                             select u;

            if (Enumerable.Count(userResult) > 0)
                MessageBox.Show("로그인 성공", "로그인 확인", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            else
                MessageBox.Show("로그인 실패", "로그인 확인", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

Enmerable.Count 는 쿼리가 실행되고 난 후, 결과 row 의 개수를 리턴해 줍니다.

 

 

3. SQL 문법 없이 사용하는 방법

2번에서 사용한 쿼리문을 다시 다음과 같이 IQueryable interface를 이용해서 다음과 같이 표현 할 수도 있습니다.

        private void btnLogin_Click(object sender, EventArgs e)
        {
            loginDataContext myDB = new loginDataContext();

            var userResult = myDB.tbl_member.Where(u => u.user_name == textUserID.Text 
                                                       && u.user_password == textUserPassword.Text);
            if (userResult.Count() > 0)
                MessageBox.Show("로그인 성공", "로그인 확인", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            else
                MessageBox.Show("로그인 실패", "로그인 확인", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

4. Single row 를 쿼리하기

로그인 화면에 [전화번호 쿼리하기] 버튼을 생성하고, 사용자 전화번호를 가져오는 퀴리를 만들어 봤습니다.

            loginDataContext myDB = new loginDataContext();

            try
            {
                tbl_member info = myDB.tbl_member.Single(u => u.user_name == textUserID.Text);
                MessageBox.Show(info.telephone);
            }
            catch(System.InvalidOperationException ex)
            {
                MessageBox.Show("사용자 입력이 잘못 되었습니다.");
            }

 

전제 소스

MyLINQ8.zip

 

posted by 따시쿵
2015. 6. 22. 11:43 C# with LINQ to SQL

Join 절에 대해서 알아 보도록 하겠습니다.

 

join 절은 개체 모델에서 직접 관계가 없는 여러 소스 시퀀스의 요소를 연결하는 데 유용합니다. 유일한 요구 사항은 각 소스의 요소가 같은지 비교할 수 있는 일부 값을 공유해야 한다는 것입니다. 예를 들어 식품 유통업체에는 특정 제품의 공급자 목록과 구매자 목록이 있을 수 있습니다. 예를 들어 해당 제품의 공급자와 구매자가 모두 동일한 특정 지역에 있는 경우 join 절을 사용하여 이러한 공급자와 구매자의 목록을 만들 수 있습니다.


join 절은 두 개의 소스 시퀀스를 입력으로 사용합니다. 각 시퀀스의 요소는 다른 시퀀스의 해당 속성과 비교할 수 있는 속성이거나 이러한 속성을 포함해야 합니다. join 절은 특별한 equals 키워드를 사용하여 지정된 키가 같은지 비교합니다. join 절에서 수행하는 모든 조인은 동등 조인입니다. join 절의 출력 모양은 수행하는 특정 조인 형식에 따라 달라집니다. 가장 일반적인 세 가지 조인 형식은 다음과 같습니다.

 

  • 내부 조인
  • 왼쪽 우선 외부 조인
  • 그룹 조인

 

1. 내부 조인 (Inner join)

 

내부 조인은 교집합과 비슷합니다. 두 데이타 원본 사이에서 일치하는 데이타들만 연결한 후 반환합니다. 내부 조인은 첫번째 데이타 원본의 데이타를 기준으로  두번째 데이타 원본이 가지고 있는 각 데이타의 특정 필드를 비교해서 일치하는 데이타들만 모아 반환합니다.

 

예를 들어 보겠습니다.

 

다음 그림에서 데이타 원본 Category는 기준이 되며, Category의 각 데이타는 Category Name, ID 를 가지고 있습니다. 그리고 Product 은 Category 에 연결할 데이타 원본이며 Product Name, CategoryID 를  갖고 있습니다. 이제 Category 의 ID 필드와 Product의 CategoryID 필드가 일치하는  데이타만 연결하면 됩니다.

 

 

내부 조인 결과에 "Grains"에 관한 데이타는 빠져 있는 것 확인 하셨나요?

내부 조인을 수행할 때 기준 데이타 원본에는 존재하지만 연결할 데이타 원본에는 존재하지 않는 데이타는 조인 결과에 포함되지 않습니다. 당연히 기준 데이타 원본에는 없지만 연결할 데이타 원본에는 존재하는 데이타의 경우에도 포함되지 않습니다.

 

내부 조인은 join 절을 통해 수행합니다. 기준 데이타 a는 from 절에서 뽑아낸 범위 변수이고, 연결 대상 데이타 b는 join 절에서 뽑아낸 변수입니다. join 절의 on 키워드는 조인 조건을 기술합니다. 이 때 on절의 조인 조건은 "동등(Equal)"만 허용합니다. "~보다 작음", "~보다 큼" 같은 비교 연산은 하락되지 않습니다. equals 키워드를 조인을 위해 따로 도입 했습니다.

 

기본 문법

 

from a in A

join b in B on a.xxxx equals b.yyyy

 

 

category와 product 클래스를 이용해서 어떻게 구현하는지는 아래와 같습니다.

        var innerJoinQuery =
            from category in categories
            join prod in products on category.ID equals prod.CategoryID
            select new { CategoryID = category.ID, CategoryName= category.Name, Product = prod.Name };

 

전체 소스

    class Program
    {
        static void Main(string[] args)
        {
            JoinDemonstration app = new JoinDemonstration();
            app.InnerJoin();

            // Keep the console window open in debug mode.
            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }
    }

    class JoinDemonstration
    {
        #region Data
        class Product
        {
            public string Name { get; set; }
            public string CategoryID { get; set; }
        }

        class Category
        {
            public string Name { get; set; }
            public string ID { get; set; }
        }

        // Specify the first data source.
        List<Category> categories = new List<Category>()
        { 
            new Category(){Name="Beverages", ID="001"},
            new Category(){Name="Condiments", ID="002"},
            new Category(){Name="Vegetables", ID="003"},
            new Category(){Name="Grains", ID="004"},
            new Category(){Name="Fruit", ID="005"}            
        };

        // Specify the second data source.
        List<Product> products = new List<Product>()
       {
          new Product{Name="Cola",  CategoryID="001"},
          new Product{Name="Tea",  CategoryID="001"},
          new Product{Name="Mustard", CategoryID="002"},
          new Product{Name="Pickles", CategoryID="002"},
          new Product{Name="Carrots", CategoryID="003"},
          new Product{Name="Bok Choy", CategoryID="003"},
          new Product{Name="Peaches", CategoryID="005"},
          new Product{Name="Melons", CategoryID="005"},
        };
        #endregion

        #region InnerJoin
        public void InnerJoin()
        {
            // Create the query that selects  
            // a property from each element. 
            var innerJoinQuery =
                from category in categories
                join prod in products on category.ID equals prod.CategoryID
                select new { CategoryID = category.ID, CategoryName= category.Name, Product = prod.Name };

            Console.WriteLine("InnerJoin:");
            // Execute the query. Access results  
            // with a simple foreach statement. 
            foreach (var item in innerJoinQuery)
            {
                Console.WriteLine("{0,-10}{1,-20}{2}", item.Product, item.CategoryName, item.CategoryID);
            }
            Console.WriteLine("InnerJoin: {0} items in 1 group.", innerJoinQuery.Count());
            Console.WriteLine(System.Environment.NewLine);

        }
        #endregion
    }

 

2. 왼쪽 우선 외부 조인(Outer join)

 

외부 조인은 기본적으로 내부 조인과 비슷하지만, 다음 그림처럼 조인 결과에 기준이 되는 데이타 원본은 모두 다 포함된다는 점이 다릅니다.

 

 

 

내부 조인을 했을 때는 "004" 데이타가 조인 결과에 없었는데, 외부 조인을 했을 때는 product name 필드가 비어 있는 상태로 조인 결과에 포함됩니다. 이것은 외부 조인이 기준이 되는 데이타 원본의 모든 데이타를 조인 결과에 반드시 포함하는 특징 때문입니다. 연결할 데이타 원본에 기준 데이타 원본의 데이타와 일치하는 데이타가 없다면 그 부분은 빈 값으로 채우게 됩니다.

 

SQL에서 지원하는 외부 조인에는 왼쪽 조인(Left Join), 오른쪽 조인(Right Join), 완전 외부 조인(Full Outer Join) 이렇게 세가지가 있습니다. 왼쪽 조인은 왼쪽 데이타 원본을 기준으로 삼아 조인을 수행하고, 오른쪽 조인은 오른쪽 데이타 원본을 기준으로 삼아 조인을 수행하며, 완전 조인은 왼쪽 오른쪽 데이타 원본 모두를 기준으로 삼습니다.

 

LINQ는 왼쪽 조인만을 지원합니다.

 

외부 조인을 사용하는 밥법은 내부 조인과 크게 다르지 않습니다. 먼저 join 절을 이용해서 조인을 수행한 후 그 결과를 임시 컬렉션에 저장하고, 이 임시 컬렉션에 대해 DefaultisEmpty 연산을 수행헤서 비어 있는 조인 결과에 빈 값을 채워 넣습니다.

            // Create the query. 
            var leftOuterQuery =
               from category in categories
               join prod in products on category.ID equals prod.CategoryID into prodGroup
               select prodGroup.DefaultIfEmpty(new Product() { Name = "Nothing!", CategoryID = category.ID });

 

LeftOuterJoin() 을 JoinDemonstration 클래스에 추가하고, 메인에서 app.LeftOuterJoin() 를 호출하면 됩니다.

 

전체 소스

        public void LeftOuterJoin()
        {
            // Create the query. 
            var leftOuterQuery =
               from category in categories
               join prod in products on category.ID equals prod.CategoryID into prodGroup
               select prodGroup.DefaultIfEmpty(new Product() { Name = "Nothing!", CategoryID = category.ID });

            // Store the count of total items (for demonstration only). 
            int totalItems = 0;

            Console.WriteLine("Left Outer Join:");

            // A nested foreach statement  is required to access group items 
            foreach (var prodGrouping in leftOuterQuery)
            {
                Console.WriteLine("Group:{0,5} ea", prodGrouping.Count());
                foreach (var item in prodGrouping)
                {
                    totalItems++;
                    Console.WriteLine("  {0,-10}{1}", item.Name, item.CategoryID);
                }
                Console.WriteLine();
            }
            Console.WriteLine("LeftOuterJoin: {0} items in {1} groups", totalItems, leftOuterQuery.Count());
            Console.WriteLine(System.Environment.NewLine);
        }
        #endregion

 

 

3. 그룹 조인

 

into 식이 있는 join 절을 그룹 조인이라고 합니다.

        var groupJoinQuery =
            from category in categories
            join prod in products on category.ID equals prod.CategoryID into prodGroup
            select prodGroup;

 

그룹 조인은 왼쪽의 데이타 원본 요소를 오른쪽의 데이타 연결 요소에 있는 하나 이상의 일치하는 요소와 연결하는 계층적 결과를 생성합니다.

 

왼쪽 데이타 원본 요소와 일치하는 오른쪽 데이타 연결 요소가 없을 경우 join 절은 해당 항목에 대해 빈 배열을 생성합니다. 따라서 그룹 조인은 결과값이 그룹으로 구성된다는 점을 제외하고는 기본적으로 내부 조인입니다.

 

다음의 method를 JoinDemonstration class 에 추가하고 main에서 호출하면 됩니다.

        #region GroupJoin
        public void GroupJoin()
        {
            var groupJoinQuery =
               from category in categories
               join prod in products on category.ID equals prod.CategoryID into prodGroup
               select prodGroup;

            // Store the count of total items (for demonstration only). 
            int totalItems = 0;

            Console.WriteLine("Simple GroupJoin:");

            // A nested foreach statement is required to access group items. 
            foreach (var prodGrouping in groupJoinQuery)
            {
                Console.WriteLine("Group:");
                foreach (var item in prodGrouping)
                {
                    totalItems++;
                    Console.WriteLine("   {0,-10}{1}", item.Name, item.CategoryID);
                }
            }
            Console.WriteLine("Unshaped GroupJoin: {0} items in {1} unnamed groups", totalItems, groupJoinQuery.Count());
            Console.WriteLine(System.Environment.NewLine);
        }
        #endregion

 

 

'C# with LINQ to SQL' 카테고리의 다른 글

LINQ - 4칙 연산(select, insert, update, delete) - DataGridView 이용  (0) 2015.07.01
LINQ - 로그인창 적용  (0) 2015.06.25
LINQ - 그룹핑2  (0) 2015.06.19
LINQ - 그룹핑1  (0) 2015.06.18
LINQ - 소개  (0) 2015.06.16
posted by 따시쿵
prev 1 2 3 4 5 6 7 ··· 38 next