티스토리 툴바



Mango 업데이트 후 Database 사용 방법[실전]

Local database에서 데이터를 저장, 검색하기 위해, Windows Phone Application은 LINQ to SQL을 사용합니다. 실제로 LINQ to SQL을 사용하는지 알아보겠습니다.
 
우선, 아래 그림과 같이 database 모델을 가정합니다

 
위의 Author Book many-to-many 이고 Publisher Book one-to-many 입니다.
Many-to-manyBook테이블의 기본 키와 Author테이블의 기본 키를 가지는 BookAuthor 테이블(link table)을 하나 생성함으로써 one-to-many 관계를 만들 수 있습니다.

 
 위 처럼 database 모델이 정해지면 위의 그림과 같이 각각 테이블과 관계를 설정합니다.

 
1. 각 테이블을 생성합니다.
 

[Table(Name="Author")]

    public class Author

    {

        [Column(IsPrimaryKey = true, DbType = "UniqueIdentifier NOT NULL")]

        public Guid AuthorId { get; set; }

 

        [Column]

        public string FirstName { get; set; }

 

        [Column]

        public string LastName { get; set; }

    }
 
클래스 위에 table이라는 어트리뷰트를 추가하고 column을 추가합니다. 기본키로 설정할 컬럼은 위와같이 설정해주시면 됩니다.
 
2. 관계를 설정합니다. (외래키)
 
다음은 관계를 설정해 줍니다. 관계를 표현하기 위해 Association 속성을 사용합니다. database의 foreign key 관계를 표현하기 위해 EntitySet<TEntity>와 EntityRef<TEntity> 타입을 함께 사용합니다. One-to-Many를 표현하기 위해 EntitySet<TEntity>와 EntityRef<TEntity> 둘 중에 하나를 사용하면 됩니다.

위의 그림은 Publisher Book One-to-Many 관계입니다.

One-to-Many 관계를 표현하는 방법으로는 두가지 방법이 있습니다.

1) EntitySet<TEntity>을 사용 : One(Publisher) Many(Book)을 가지고 있는 방법입니다.

    [Table]

    public class Publisher

    {

        public Publisher()

        {

            _books = new EntitySet<Book>();

        }

        private EntitySet<Book> _books;

 

        [Association(Storage = "_books", OtherKey = "PublisherId")]

        public EntitySet<Book> Books

        {

            get

            {

                return this._books;

            }

            set

            {

                this._books.Assign(value);

            }

        }

    }


 

2) EntityRef<TEntity> 사용 : Many(Book) 안에서 One(Publisher)를 참조하는 방법.

[Table(Name="Book")]

    public class Book

    {

        [Column]

        public Guid PublisherId;

 

        private EntityRef<Publisher> _pulisher;

 

        [Association(Storage = "_pulisher", ThisKey = "PublisherId")]

        public Publisher Publisher

        {

            get

            {

                return this._pulisher.Entity;

            }

            set

            {

                this._pulisher.Entity = value;

            }

        }

    }


 

여기서 주의할 점은 One-to-Many 관계예서 EntitySet<TEntity>를 사용하면 One -> Many를 접근할 수 있고 EntityRef<TEntity>를 사용하면 Many -> One으로 단 방향 접근이 가능합니다. 만약 양방향 접근을 가능하게 하고 싶다면 EntitySet<TEntity> EntityRef<TEntity>를 함께 사용하든지 linq에서 foregin key로 조인을 해서 값을 가져오면 됩니다.

여기에서는 Book이 주 객체이므로 EntityRef<TEntity>를 사용하였습니다.
 

3. DataContext 생성합니다.

 
DataContext database로부터 objects들을 검색, 다시 submit change 등을 위한 중요한 통로입니다.


 

public class DataContextBase : DataContext

    {

        public DataContextBase(string connect)

            : base(connect)

        {

        }

        public DataContextBase(string connect, MappingSource mappingSource)

            : base(connect, mappingSource)

        {

        }

        public Table<Book> Books

        {

            get

            {

                return this.GetTable<Book>();

            }

        }

        public Table<Author> Authors

        {

            get

            {

                return this.GetTable<Author>();

            }

        }

        public Table<BookAuthor> BookAuthors

        {

            get

            {

                return this.GetTable<BookAuthor>();

            }

        }

        public Table<Publisher> Publishers

        {

            get

            {

                return this.GetTable<Publisher>();

            }

        }

    }
 

4. Database를 생성합니다.
 

DataContext는 생성자에 넘겨주는 연결 스트링과 함께 최기화 됩니다.

            _db = new DataContextBase("isostore:/BookDB.sdf");

   

Database 생성은 처음에 한번만 합니다.

        private static void CreateDatabase()

        {

            //연결 스트링으로 DataContext 생성한다.

            _db = new DataContextBase("isostore:/BookDB.sdf");

 

            // 데이터베이스가 존재하지 않을 데이터베이스를 생성한다.

            if (_db.DatabaseExists() == true)

            {

                return;

            }

 

            try

            {

                _db.CreateDatabase();

               

                GenerateSystemData();

                _db.SubmitChanges();

            }

            catch (Exception ex)

            {

                Debug.Assert(false, "CreateDatabase Error", ex.Message);

                throw;

            }

        }


 

5. Book 추가하기

우선 Author Publisher를 객체를 생성합니다.

_db.Authors.InsertOnSubmit(new Author()

            {

                AuthorId = Guid.NewGuid(),

                FirstName = "은미",

                LastName = "",

            });

_db.Publishers.InsertOnSubmit(new Publisher()

            {

                PublisherId = Guid.NewGuid(),

                Name = "한빛미디어",

                City = "서울"

            });

 

다음은 Book 객체를 생성합니다. Book에서는 Pulisher의 아이디를 설정해주며 관계가 형성됩니다. , A.PublisherId = B 이면 "A라는 책의 출판사는 B이다"라는 관계가 만들어지는 것입니다.

            Book book = new Book()

            {

                BookId = Guid.NewGuid(),

                PublicationDate = DateTime.Now,

                Title = Title,

                PublisherId = SelectedPublisher.PublisherId,

            };

            _db.Books.InsertOnSubmit(book);
 

작가와 책은 Many-to-Many One-to-Many 관계로 바꾸면서 BookAuthor table(Link table)을 생성했습니다. 그러므로 BookAuthor tableBookId AuthorId를 가지는 레코드를 추가하므로 관계가 생성됩니다.

       BookAuthor ba = new BookAuthor()

            {

                BookAuthorId = Guid.NewGuid(),

                AuthorId = SelectedAuthor.AuthorId,

                BookId = book.BookId,

            };

            _db.BookAuthors.InsertOnSubmit(ba);

 

6. Book 조회하기.

현재 존재하는 Book의 작가, 출판사 정보를 가져오려면 Book을 모두 가져온 이후 점(dot)을 이용해 Author Publisher에 접근하면 됩니다.

            var list = from c in _db.Books

                       select c;

 

            ObservableCollection<BookMeta> books = new ObservableCollection<BookMeta>();

            foreach (var item in list)

            {

                foreach (var author in item.BookAuthors)

                {

                    books.Add(new BookMeta()

                    {

                        Title = item.Title,

                        AuthorFirstName = author.Author.FirstName,

                        AuthorLastName = author.Author.LastName,

                        PublisherCity = item.Publisher.City,

                        PublisherName = item.Publisher.Name,

                    });

                }

            }

 

            Books = books;

 
[참고] http://msdn.microsoft.com/en-us/library/hh202860(v=VS.92).aspx

저작자 표시
Trackback 0 Comment 1