Entity Framework-첫 번째 예

클래스를 사용하여 매우 간단한 모델을 정의 해 봅시다. Program.cs 파일에서 정의하고 있지만 실제 응용 프로그램에서는 클래스를 별도의 파일과 잠재적으로 별도의 프로젝트로 분할합니다. 다음은 Code First 접근 방식을 사용하여 생성 할 데이터 모델입니다.

모델 생성

Student 클래스에 대해 다음 코드를 사용하여 Program.cs 파일에 다음 세 가지 클래스를 추가합니다.

public class Student {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}
  • ID 속성은이 클래스에 해당하는 데이터베이스 테이블의 기본 키 열이됩니다.

  • Enrollments 속성은 탐색 속성입니다. 탐색 속성에는이 엔터티와 관련된 다른 엔터티가 포함됩니다.

  • 이 경우 Student 엔터티의 Enrollments 속성에는 해당 Student 엔터티와 관련된 모든 Enrollment 엔터티가 포함됩니다.

  • 탐색 속성은 일반적으로 가상으로 정의되므로 지연로드와 같은 특정 Entity Framework 기능을 활용할 수 있습니다.

  • 탐색 속성이 여러 엔터티를 보유 할 수있는 경우 (다 대다 또는 일토 마니 관계에서와 같이) 해당 유형은 ICollection과 같이 항목을 추가, 삭제 및 업데이트 할 수있는 목록이어야합니다.

다음은 Course 클래스의 구현입니다.

public class Course {
   public int CourseID { get; set; }
   public string Title { get; set; }
   public int Credits { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Enrollments 속성은 탐색 속성입니다. 과정 엔터티는 여러 등록 엔터티와 관련 될 수 있습니다.

다음은 Enrollment 클래스 및 열거 형에 대한 구현입니다.

public enum Grade {
   A, B, C, D, F
}

public class Enrollment {
   public int EnrollmentID { get; set; }
   public int CourseID { get; set; }
   public int StudentID { get; set; }
   public Grade? Grade { get; set; }
	
   public virtual Course Course { get; set; }
   public virtual Student Student { get; set; }
}
  • EnrollmentID 속성이 기본 키가됩니다.

  • Grade 속성은 열거 형입니다. Grade 유형 선언 뒤의 물음표는 Grade 속성이 nullable임을 나타냅니다.

  • null 인 등급은 0 등급과 다릅니다. Null은 성적이 알려지지 않았거나 아직 할당되지 않았 음을 의미합니다.

  • StudentID 및 CourseID 속성은 외래 키이고 해당 탐색 속성은 Student 및 Course입니다.

  • Enrollment 엔터티는 하나의 Student 및 하나의 Course 엔터티와 연결되므로 속성은 단일 Student 및 Course 엔터티 만 보유 할 수 있습니다.

데이터베이스 컨텍스트 생성

지정된 데이터 모델에 대한 Entity Framework 기능을 조정하는 기본 클래스는 데이터를 쿼리하고 저장할 수있는 데이터베이스 컨텍스트 클래스입니다. DbContext 클래스에서 파생되고 형식화 된 DbSet을 노출하여이 클래스를 만들 수 있습니다. 모델의 각 클래스에 대해. 다음은 DbContext 클래스에서 파생 된 MyContext 클래스의 구현입니다.

public class MyContext : DbContext {
   public virtual DbSet<Course> Courses { get; set; }
   public virtual DbSet<Enrollment> Enrollments { get; set; }
   public virtual DbSet<Student> Students { get; set; }
}

다음은 Program.cs 파일의 전체 코드입니다.

using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EFCodeFirstDemo {

   class Program {
      static void Main(string[] args) {}
   }

   public enum Grade {
      A, B, C, D, F
   }

   public class Enrollment {
      public int EnrollmentID { get; set; }
      public int CourseID { get; set; }
      public int StudentID { get; set; }
      public Grade? Grade { get; set; }
		
      public virtual Course Course { get; set; }
      public virtual Student Student { get; set; }
   }

   public class Student {
      public int ID { get; set; }
      public string LastName { get; set; }
      public string FirstMidName { get; set; }
      public DateTime EnrollmentDate { get; set; }
		
      public virtual ICollection<Enrollment> Enrollments { get; set; }
   }

   public class Course {
      public int CourseID { get; set; }
      public string Title { get; set; }
      public int Credits { get; set; }
		
      public virtual ICollection<Enrollment> Enrollments { get; set; }
   }

   public class MyContext : DbContext {
      public virtual DbSet<Course> Courses { get; set; }
      public virtual DbSet<Enrollment> Enrollments { get; set; }
      public virtual DbSet<Student> Students { get; set; }
   }

}

위의 코드는 데이터 저장 및 검색을 시작하는 데 필요한 전부입니다. 데이터를 추가 한 다음 검색해 보겠습니다. 다음은 주요 방법의 코드입니다.

static void Main(string[] args) {

   using (var context = new MyContext()) {
      // Create and save a new Students
      Console.WriteLine("Adding new students");

      var student = new Student {
         FirstMidName = "Alain", LastName = "Bomer", 
            EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
      };

      context.Students.Add(student);
		
      var student1 = new Student {
         FirstMidName = "Mark", LastName = "Upston", 
            EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
      };

      context.Students.Add(student1);
      context.SaveChanges();

      // Display all Students from the database
      var students = (from s in context.Students 
         orderby s.FirstMidName select s).ToList<Student>();

      Console.WriteLine("Retrieve all Students from the database:");

      foreach (var stdnt in students) {
         string name = stdnt.FirstMidName + " " + stdnt.LastName;
         Console.WriteLine("ID: {0}, Name: {1}", stdnt.ID, name);
      }
		
      Console.WriteLine("Press any key to exit...");
      Console.ReadKey();
   }
}

위의 코드가 실행되면 다음과 같은 출력을 받게됩니다.

Adding new students
Retrieve all Students from the database:
ID: 1, Name: Alain Bomer
ID: 2, Name: Mark Upston
Press any key to exit...

이제 떠오르는 질문은 우리가 데이터를 추가 한 다음 데이터베이스에서 검색 한 데이터와 데이터베이스는 어디에 있습니까? 규칙에 따라 DbContext는 데이터베이스를 생성했습니다.

  • 로컬 SQL Express 인스턴스를 사용할 수있는 경우 Code First는 해당 인스턴스에 데이터베이스를 생성 한 것입니다.

  • SQL Express를 사용할 수없는 경우 Code First는 LocalDb를 사용합니다.

  • 데이터베이스는 파생 된 컨텍스트의 정규화 된 이름을 따라 이름이 지정됩니다.

이 경우 SQL Express 인스턴스를 사용할 수 있으며 다음 이미지와 같이 데이터베이스 이름은 EFCodeFirstDemo.MyContext입니다.

  • 이것은 기본 규칙 일 뿐이며 Code First가 사용하는 데이터베이스를 변경하는 다양한 방법이 있습니다.

  • 위 이미지에서 볼 수 있듯이 Student, Courses 및 Enrollments 테이블이 생성되었으며 각 테이블에는 적절한 데이터 유형과 길이가있는 열이 포함되어 있습니다.

  • 열 이름과 데이터 유형은 각 도메인 클래스의 속성과도 일치합니다.

데이터베이스 초기화

위의 예에서는 Code First가 데이터베이스를 자동으로 생성하는 것을 보았지만 데이터베이스와 서버의 이름을 변경하려면 Code First가 데이터베이스를 초기화하는 동안 데이터베이스 이름과 서버를 결정하는 방법을 살펴 보겠습니다. 다음 다이어그램을 살펴보십시오.

다음과 같은 방법으로 컨텍스트 클래스의 기본 생성자를 정의 할 수 있습니다.

  • 매개 변수 없음
  • 데이터베이스 이름
  • 연결 문자열 이름

매개 변수 없음

위의 예와 같이 매개 변수없이 컨텍스트 클래스의 기본 생성자를 지정하면 엔티티 프레임 워크는 이름이 {Namespace}. {Context class name} 인 로컬 SQLEXPRESS 서버에 데이터베이스를 생성합니다.

위의 예에서 자동으로 생성되는 데이터베이스의 이름은 EFCodeFirstDemo.MyContext입니다. 이름을 보면 다음 코드와 같이 EFCodeFirstDemo가 네임 스페이스이고 MyContext가 컨텍스트 클래스 이름임을 알 수 있습니다.

public class MyContext : DbContext {
   public MyContext() : base() {}

   public virtual DbSet<Course> Courses { get; set; }
   public virtual DbSet<Enrollment> Enrollments { get; set; }
   public virtual DbSet<Student> Students { get; set; }
}

데이터베이스 이름

컨텍스트 클래스의 기본 생성자에서 데이터베이스 이름을 매개 변수로 전달하면 Code First는 자동으로 데이터베이스를 다시 생성하지만 이번에는 로컬 SQLEXPRESS 데이터베이스 서버의 기본 생성자에서 매개 변수로 전달되는 이름이됩니다. .

다음 코드에서 MyContextDB는 기본 생성자에서 매개 변수로 지정됩니다. 애플리케이션을 실행하면 MyContextDB 이름의 데이터베이스가 로컬 SQL 서버에 생성됩니다.

public class MyContext : DbContext {
   public MyContext() : base("MyContextDB") {}
   public virtual DbSet<Course> Courses { get; set; }
   public virtual DbSet<Enrollment> Enrollments { get; set; }
   public virtual DbSet<Student> Students { get; set; }
}

연결 문자열 이름

이것은 DbContext에 SQL Express 또는 LocalDb 이외의 데이터베이스 서버를 사용하도록 지시하는 쉬운 방법입니다. app.config 파일에 연결 문자열을 넣도록 선택할 수 있습니다.

  • 연결 문자열의 이름이 컨텍스트의 이름과 일치하면 (네임 스페이스 한정 여부에 관계없이) DbContext에서 매개 변수 less 생성자를 사용할 때이를 찾습니다.

  • 연결 문자열 이름이 컨텍스트 이름과 다른 경우 DbContext 생성자에 연결 문자열 이름을 전달하여 코드 우선 모드에서이 연결을 사용하도록 DbContext에 지시 할 수 있습니다.

public class MyContext : DbContext {
   public MyContext() : base("name = MyContextDB") {}
   public virtual DbSet<Course> Courses { get; set; }
   public virtual DbSet<Enrollment> Enrollments { get; set; }
   public virtual DbSet<Student> Students { get; set; }
}
  • 위 코드에서 컨텍스트 클래스 연결 문자열의 스 니펫은 기본 생성자에서 매개 변수로 지정됩니다.

  • 연결 문자열 이름은 "name ="으로 시작해야합니다. 그렇지 않으면 데이터베이스 이름으로 간주됩니다.

  • 이 형식은 구성 파일에서 연결 문자열을 찾을 것으로 예상 함을 명시합니다. 주어진 이름의 연결 문자열을 찾을 수 없으면 예외가 발생합니다.

<connectionStrings>
   <add name = "MyContextDB"
      connectionString = "Data Source =.;Initial Catalog = EFMyContextDB;Integrated Security = true"
      providerName = "System.Data.SqlClient"/>
</connectionStrings>
  • app.config의 연결 문자열에있는 데이터베이스 이름은 다음과 같습니다. EFMyContextDB. CodeFirst는 새로운EFMyContextDB 데이터베이스 또는 기존 사용 EFMyContextDB 로컬 SQL Server의 데이터베이스.

도메인 클래스

지금까지 EF가 기본 규칙을 사용하여 모델을 검색하도록했습니다.하지만 클래스가 규칙을 따르지 않고 추가 구성을 수행 할 수 있어야하는 경우가 있습니다. 그러나 EF에 필요한 정보를 제공하도록 도메인 클래스를 구성하여 이러한 규칙을 재정의 할 수 있습니다. 도메인 클래스를 구성하는 두 가지 옵션이 있습니다-

  • 데이터 주석
  • Fluent API

데이터 주석

DataAnnotations는 가장 일반적으로 필요한 구성을 강조하는 클래스를 구성하는 데 사용됩니다. DataAnnotations는 ASP.NET MVC와 같은 여러 .NET 응용 프로그램에서도 이해되며, 이러한 응용 프로그램은 클라이언트 측 유효성 검사에 동일한 주석을 활용할 수 있습니다.

다음은 학생 수업에서 사용되는 데이터 주석입니다.

public class Enrollment {

   [Key]
   public int EnrollmentID { get; set; }
   public int CourseID { get; set; }
   public int StudentID { get; set; }
   public Grade? Grade { get; set; }

   [ForeignKey("CourseID")]
   public virtual Course Course { get; set; }

   [ForeignKey("ID")]
   public virtual Student Student { get; set; }
}

Fluent API

대부분의 모델 구성은 간단한 데이터 주석을 사용하여 수행 할 수 있습니다. Fluent API는 데이터 주석으로 수행 할 수없는 일부 고급 구성 외에도 데이터 주석으로 수행 할 수있는 모든 작업을 포함하는 모델 구성을 지정하는 고급 방법입니다. 데이터 주석과 유창한 API를 함께 사용할 수 있습니다.

유창한 API에 액세스하려면 DbContext에서 OnModelCreating 메서드를 재정의합니다. 이제 다음 코드와 같이 student 테이블의 열 이름을 FirstMidName에서 FirstName으로 바꿉니다.

public class MyContext : DbContext {

   protected override void OnModelCreating(DbModelBuilder modelBuilder) {
      modelBuilder.Entity<Student>().Property(s ⇒ s.FirstMidName)
         .HasColumnName("FirstName");
   }

   public virtual DbSet<Course> Courses { get; set; }
   public virtual DbSet<Enrollment> Enrollments { get; set; }
   public virtual DbSet<Student> Students { get; set; }
}