티스토리 뷰

반응형

Working with an Existing Database

Entity Framework Core 시작(1/5) (tistory.com)

 

1번에서는 Code를 이용해서 Database를 만들고 연결하고 사용하는 방법을 알아 보았습니다. 이 방법은 Code-first라고 부릅니다.

이번 회차에서는 Database가 존재하는 상태에서 Code를 만드는 방법을 알아보도록 하겠습니다. 이런 방법을 Database-first라고 이야기 합니다.

이번에 사용할 데이터베이스는 1번에서 만들었던 데이터베이스를 그대로 이용합니다.

 

데이터베이스 구조는 아래와 같습니다.

 

콘솔앱을 생성합니다.

Console App(.NET Core), Project name : ContosoPets2

앱을 생성하는 방법과 NuGet package를 추가하는 방법은 1번을 참고합니다.

 

Code 생성1

Tools, NuGet Packages Manager, Package Manager Console 창을 열고 아래 코드를 입력합니다.

Scaffold-DbContext "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=ContosoPets;Integrated Security=True;ConnectRetryCount=0"  Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Context ContosoPetsContext

 

Models 폴더를 확인

Models 폴더가 생성되고 클래스가 생성된 것이 확인 됩니다.

 

Customer.cs 파일 확인합니다.

1번과는 다르게 프로퍼티에 DataAnnotation이 존재하지 않습니다.

    public partial class Customers
    {
        public Customers()
        {
            Orders = new HashSet<Orders>();
        }

        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Address { get; set; }
        public string Phone { get; set; }
        public string Email { get; set; }

        public virtual ICollection<Orders> Orders { get; set; }
    }

그렇다면, 각 필드들의 제약 사항들은 어디에 있을까요?

ContosoPetsContext.cs 파일을 확인합니다.

    public partial class ContosoPetsContext : DbContext
    {
        public ContosoPetsContext()
        {
        }

        public ContosoPetsContext(DbContextOptions<ContosoPetsContext> options)
            : base(options)
        {
        }

        public virtual DbSet<Customers> Customers { get; set; }
        public virtual DbSet<Orders> Orders { get; set; }
        public virtual DbSet<ProductOrders> ProductOrders { get; set; }
        public virtual DbSet<Products> Products { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.
                optionsBuilder.UseSqlServer("Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=ContosoPets;Integrated Security=True;ConnectRetryCount=0");
            }
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Customers>(entity =>
            {
                entity.Property(e => e.Email)
                    .IsRequired()
                    .HasDefaultValueSql("(N'')");

                entity.Property(e => e.FirstName).IsRequired();

                entity.Property(e => e.LastName).IsRequired();
            });

            modelBuilder.Entity<Orders>(entity =>
            {
                entity.HasIndex(e => e.CustomerId);

                entity.HasOne(d => d.Customer)
                    .WithMany(p => p.Orders)
                    .HasForeignKey(d => d.CustomerId);
            });

            modelBuilder.Entity<ProductOrders>(entity =>
            {
                entity.HasIndex(e => e.OrderId);

                entity.HasIndex(e => e.ProductId);

                entity.HasOne(d => d.Order)
                    .WithMany(p => p.ProductOrders)
                    .HasForeignKey(d => d.OrderId);

                entity.HasOne(d => d.Product)
                    .WithMany(p => p.ProductOrders)
                    .HasForeignKey(d => d.ProductId);
            });

            modelBuilder.Entity<Products>(entity =>
            {
                entity.Property(e => e.Name).IsRequired();

                entity.Property(e => e.Price).HasColumnType("decimal(18, 2)");
            });

            OnModelCreatingPartial(modelBuilder);
        }

        partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
    }

OnModelCreating 메소드는 데이터베이스가 생성될 때 어떤 속성을 추가할지를 지정할 수 있는 곳입니다.

그런데, Customer 클래스를 사용하는 입장에서는 프로퍼티에 DataAnnotation이 붙어있는 것이 더 좋습니다.

 

Code 생성2

기존에 생성된 Models 폴더, 모델과 Context를 삭제합니다.

Package Manager Console을 열고 아래 코드를 입력합니다.

Scaffold-DbContext "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=ContosoPets;Integrated Security=True;ConnectRetryCount=0" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Context ContosoPetsContext -DataAnnotations

Customer.cs 파일을 확인합니다.

    public partial class Customers
    {
        public Customers()
        {
            Orders = new HashSet<Orders>();
        }

        [Key]
        public int Id { get; set; }
        [Required]
        public string FirstName { get; set; }
        [Required]
        public string LastName { get; set; }
        public string Address { get; set; }
        public string Phone { get; set; }
        [Required]
        public string Email { get; set; }

        [InverseProperty("Customer")]
        public virtual ICollection<Orders> Orders { get; set; }
    }

이렇게 모델을 생성하면, 사용하기가 훨씬 수월합니다.

 

Scaffold-DbContext를 이용해서 이미 만들어진 Database의 테이블과 컬럼들을 Code로 손쉽게 만들 수 있습니다.

Scaffold-DbContext에 대한 더 자세한 사항은 여기를 참고합니다.

Managing Database Schemas에 대한 더 자세한 사항은 여기를 참고합니다.

 

반응형

'Entity Framework Core' 카테고리의 다른 글

Entity Framework Core 시작(3/5)  (0) 2020.12.28
SQL Sever Express vs SQLite  (0) 2020.12.27
Entity Framework Core 시작(1/5)  (0) 2020.12.16
Entity Framework Core 링크 정리  (0) 2020.12.14
Announcing the Release of EF Core 5.0  (0) 2020.12.10
댓글