Entity Framework
코드 첫 번째 데이터 주석
수색…
비고
Entity Framework Code-First는 도메인 클래스 및 속성에 적용 할 수있는 DataAnnotation 특성 집합을 제공합니다. DataAnnotation 속성은 기본 Code-First 규칙보다 우선합니다.
- System.ComponentModel.DataAnnotations 에는 Null 허용 여부 또는 열 크기에 영향을주는 특성이 포함됩니다.
- System.ComponentModel.DataAnnotations.Schema 네임 스페이스에는 데이터베이스의 스키마에 영향을주는 특성이 포함되어 있습니다.
주 : DataAnnotation은 구성 옵션의 서브 세트만을 제공합니다. Fluent API는 Code-First에서 사용할 수있는 모든 구성 옵션을 제공합니다.
[Key] 속성
키는 데이터베이스 테이블의 각 행 / 레코드를 고유하게 식별하는 테이블의 필드입니다.
이 속성을 사용 하여 기본 Code-First 규칙 을 무시하십시오 . 속성에 적용되면이 클래스의 기본 키 열로 사용됩니다.
using System.ComponentModel.DataAnnotations;
public class Person
{
[Key]
public int PersonKey { get; set; } // <- will be used as primary key
public string PersonName { get; set; }
}
복합 기본 키가 필요한 경우 [Key] 속성을 여러 속성에 추가 할 수도 있습니다. 복합 키 내의 열 순서는 [ 키, 열 (순서 = x)] 형식으로 제공되어야합니다.
using System.ComponentModel.DataAnnotations;
public class Person
{
[Key, Column(Order = 0)]
public int PersonKey1 { get; set; } // <- will be used as part of the primary key
[Key, Column(Order = 1)]
public int PersonKey2 { get; set; } // <- will be used as part of the primary key
public string PersonName { get; set; }
}
[Key] 특성이 없으면 EntityFramework는 클래스의 속성을 "Id"또는 "{ClassName} Id"라는 기본 키로 사용하는 기본 규칙으로 되돌아갑니다.
public class Person
{
public int PersonID { get; set; } // <- will be used as primary key
public string PersonName { get; set; }
}
[필수] 속성
도메인 클래스의 속성에 적용되면 데이터베이스는 NOT NULL 열을 만듭니다.
using System.ComponentModel.DataAnnotations;
public class Person
{
public int PersonID { get; set; }
[Required]
public string PersonName { get; set; }
}
NOT NULL 제약 조건을 가진 결과 컬럼 :
참고 : 유효성 검사 속성으로 asp.net-mvc와 함께 사용할 수도 있습니다.
[MaxLength] 및 [MinLength] 특성
[MaxLength (int)] 특성은 도메인 클래스의 문자열 또는 배열 형식 속성에 적용 할 수 있습니다. Entity Framework는 열의 크기를 지정된 값으로 설정합니다.
using System.ComponentModel.DataAnnotations;
public class Person
{
public int PersonID { get; set; }
[MinLength(3), MaxLength(100)]
public string PersonName { get; set; }
}
지정된 열 길이를 갖는 결과 열 :
[MinLength (int)] 특성은 유효성 검사 특성이며 데이터베이스 구조에는 영향을주지 않습니다. PersonName이 3 자보다 작은 Person을 삽입 / 업데이트하려고하면이 커밋은 실패합니다. 우리는 처리해야 할 DbUpdateConcurrencyException
을 얻습니다.
using (var db = new ApplicationDbContext())
{
db.Staff.Add(new Person() { PersonName = "ng" });
try
{
db.SaveChanges();
}
catch (DbEntityValidationException ex)
{
//ErrorMessage = "The field PersonName must be a string or array type with a minimum length of '3'."
}
}
[MaxLength] 및 [MinLength] 특성은 유효성 검사 특성으로 asp.net-mvc와 함께 사용할 수도 있습니다.
[범위 (최소, 최대)] 속성
속성의 숫자 최소값과 최대 값 범위를 지정합니다.
using System.ComponentModel.DataAnnotations;
public partial class Enrollment
{
public int EnrollmentID { get; set; }
[Range(0, 4)]
public Nullable<decimal> Grade { get; set; }
}
Grade를 범위 밖의 값으로 삽입 / 업데이트하려고하면이 커밋은 실패합니다. 우리는 처리해야 할 DbUpdateConcurrencyException
을 얻습니다.
using (var db = new ApplicationDbContext())
{
db.Enrollments.Add(new Enrollment() { Grade = 1000 });
try
{
db.SaveChanges();
}
catch (DbEntityValidationException ex)
{
// Validation failed for one or more entities
}
}
유효성 검사 속성으로 asp.net-mvc와 함께 사용할 수도 있습니다.
결과:
[DatabaseGenerated] 특성
데이터베이스에서 속성 값을 생성하는 방법을 지정합니다. 가능한 값은 세 가지입니다.
-
None
은 데이터베이스에서 값을 생성하지 않도록 지정합니다. -
Identity
는 열이 기본 정수 키에 일반적으로 사용되는 ID 열 임을 지정합니다. -
Computed
는 데이터베이스가 열의 값을 생성하도록 지정합니다.
값이 None
이 아닌 경우 Entity Framework는 속성에 대한 변경 내용을 다시 데이터베이스에 커밋하지 않습니다.
기본적으로 ( StoreGeneratedIdentityKeyConvention
에 따라) 정수 키 등록 정보는 식별 컬럼으로 처리됩니다. 이 규 "을 겹쳐 쓰고 비 식별 C 럼으로 처리되도록하려면 None
값으로 DatabaseGenerated
속성을 사용할 수 있습니다.
using System.ComponentModel.DataAnnotations.Schema;
public class Foo
{
[Key]
public int Id { get; set; } // identity (auto-increment) column
}
public class Bar
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; } // non-identity column
}
다음 SQL은 계산 열이있는 테이블을 만듭니다.
CREATE TABLE [Person] (
Name varchar(100) PRIMARY KEY,
DateOfBirth Date NOT NULL,
Age AS DATEDIFF(year, DateOfBirth, GETDATE())
)
GO
위 테이블의 레코드를 나타내는 엔티티를 작성하려면 DatabaseGenerated
속성을 Computed
값과 함께 사용해야합니다.
[Table("Person")]
public class Person
{
[Key, StringLength(100)]
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public int Age { get; set; }
}
[NotMapped] 속성
코드 첫 번째 규칙에 따라 Entity Framework는 지원되는 데이터 형식이며 getter와 setter가 모두있는 모든 공용 속성에 대한 열을 만듭니다. [NotMapped] 주석은 데이터베이스 테이블의 열을 원하지 않는 속성에 적용되어야합니다.
데이터베이스에 저장하고 싶지 않은 속성의 예는 이름과 성을 기반으로 한 학생의 전체 이름입니다. 즉석에서 계산할 수 있으며 데이터베이스에 저장할 필요가 없습니다.
public string FullName => string.Format("{0} {1}", FirstName, LastName);
"FullName"속성에는 getter 및 setter 만 있으므로 기본적으로 Entity Framework에서는 기본적으로 열을 만들지 않습니다 .
데이터베이스에 저장하고 싶지 않은 속성의 또 다른 예는 학생의 "AverageGrade"입니다. 우리는 주문에 따라 AverageGrade를 얻고 싶지 않습니다. 대신 우리는 그것을 계산하는 다른 곳에서 루틴을 가질 수 있습니다.
[NotMapped]
public float AverageGrade { set; get; }
"AverageGrade"는 [NotMapped] 주석으로 표시되어야하며, 그렇지 않으면 Entity Framework에서 해당 열을 만듭니다.
using System.ComponentModel.DataAnnotations.Schema;
public class Student
{
public int Id { set; get; }
public string FirstName { set; get; }
public string LastName { set; get; }
public string FullName => string.Format("{0} {1}", FirstName, LastName);
[NotMapped]
public float AverageGrade { set; get; }
}
위의 엔터티에 대해서는 DbMigration.cs
볼 수 있습니다.
CreateTable(
"dbo.Students",
c => new
{
Id = c.Int(nullable: false, identity: true),
FirstName = c.String(),
LastName = c.String(),
})
.PrimaryKey(t => t.Id);
및 SQL Server Management Studio
[표] 속성
[Table("People")]
public class Person
{
public int PersonID { get; set; }
public string PersonName { get; set; }
}
Entity Framework에서 생성하는 대신 특정 테이블 이름을 사용하도록 지시 (예 : Person
또는 Persons
)
[Table] 속성을 사용하여 테이블에 대한 스키마를 지정할 수도 있습니다.
[Table("People", Schema = "domain")]
[Column] 속성
public class Person
{
public int PersonID { get; set; }
[Column("NameOfPerson")]
public string PersonName { get; set; }
}
Entity Framework에서 속성 이름을 사용하는 대신 특정 열 이름을 사용하도록 지시합니다. 또한 테이블에서 데이터베이스 데이터 유형과 열 순서를 지정할 수 있습니다.
[Column("NameOfPerson", TypeName = "varchar", Order = 1)]
public string PersonName { get; set; }
[색인] 속성
public class Person
{
public int PersonID { get; set; }
public string PersonName { get; set; }
[Index]
public int Age { get; set; }
}
열 또는 열 집합에 대한 데이터베이스 인덱스를 만듭니다.
[Index("IX_Person_Age")]
public int Age { get; set; }
이렇게하면 특정 이름의 색인이 작성됩니다.
[Index(IsUnique = true)]
public int Age { get; set; }
고유 색인이 작성됩니다.
[Index("IX_Person_NameAndAge", 1)]
public int Age { get; set; }
[Index("IX_Person_NameAndAge", 2)]
public string PersonName { get; set; }
이것은 2 개의 열을 사용하여 복합 색인을 작성합니다. 이렇게하려면 동일한 색인 이름을 지정하고 열 순서를 제공해야합니다.
참고 : Index 특성은 Entity Framework 6.1에 도입되었습니다. 이전 버전을 사용하는 경우이 섹션의 정보는 적용되지 않습니다.
[ForeignKey (string)] 특성
EF 규칙을 따르지 않는 외래 키가 필요한 경우 사용자 지정 외래 키 이름을 지정합니다.
public class Person
{
public int IdAddress { get; set; }
[ForeignKey(nameof(IdAddress))]
public virtual Address HomeAddress { get; set; }
}
동일한 엔티티 유형에 대해 여러 개의 관계가있을 때도 사용할 수 있습니다.
using System.ComponentModel.DataAnnotations.Schema;
public class Customer
{
...
public int MailingAddressID { get; set; }
public int BillingAddressID { get; set; }
[ForeignKey("MailingAddressID")]
public virtual Address MailingAddress { get; set; }
[ForeignKey("BillingAddressID")]
public virtual Address BillingAddress { get; set; }
}
ForeignKey
특성이 없으면 EF가 MailingAddress
가져올 때 BillingAddressID
값을 사용하거나 자체 명명 규칙 (예 : Address_MailingAddress_Id
)을 기반으로하는 열의 다른 이름을 사용하여 해당 값을 사용하려고 할 수 있습니다 대신 기존 데이터베이스와 함께 사용하는 경우 오류가 발생합니다.
[StringLength (int)] 특성
using System.ComponentModel.DataAnnotations;
public class Post
{
public int Id { get; set; }
[StringLength(100)]
public string Title { get; set;}
[StringLength(300)]
public string Abstract { get; set; }
public string Description { get; set; }
}
문자열 필드의 최대 길이를 정의합니다.
참고 : 유효성 검사 속성으로 asp.net-mvc와 함께 사용할 수도 있습니다.
[Timestamp] 속성
[TimeStamp] 속성은 지정된 Entity 클래스의 1 바이트 배열 속성에만 적용 할 수 있습니다. Entity Framework는 해당 속성의 데이터베이스 테이블에 null이 아닌 타임 스탬프 열을 만듭니다. Entity Framework는 동시성 검사에서이 TimeStamp 열을 자동으로 사용합니다.
using System.ComponentModel.DataAnnotations.Schema;
public class Student
{
public int Id { set; get; }
public string FirstName { set; get; }
public string LastName { set; get; }
[Timestamp]
public byte[] RowVersion { get; set; }
}
[ConcurrencyCheck] 특성
이 속성은 class 속성에 적용됩니다. 동시성 검사에 기존 열을 사용하고 동시성에 대해 별도의 시간 소인 열을 사용하지 않으려는 경우 ConcurrencyCheck 특성을 사용할 수 있습니다.
using System.ComponentModel.DataAnnotations;
public class Author
{
public int AuthorId { get; set; }
[ConcurrencyCheck]
public string AuthorName { get; set; }
}
위의 예에서 ConcurrencyCheck 특성은 Author 클래스의 AuthorName 속성에 적용됩니다. 따라서 코드 - 퍼스트는 낙천적 동시성을 검사하기 위해 업데이트 명령 (Where 절)에 AuthorName 열을 포함시킵니다.
[InverseProperty (string)] 특성
using System.ComponentModel.DataAnnotations.Schema;
public class Department
{
...
public virtual ICollection<Employee> PrimaryEmployees { get; set; }
public virtual ICollection<Employee> SecondaryEmployees { get; set; }
}
public class Employee
{
...
[InverseProperty("PrimaryEmployees")]
public virtual Department PrimaryDepartment { get; set; }
[InverseProperty("SecondaryEmployees")]
public virtual Department SecondaryDepartment { get; set; }
}
InverseProperty 여러 양방향 관계는 두 엔티티 사이에 존재하는 경우 두 가지 방법으로 관계를 식별 할 수 있습니다.
Entity Framework에 탐색 속성이 다른 쪽의 속성과 일치해야한다고 알려줍니다.
Entity Framework는 두 엔터티간에 여러 양방향 관계가있는 경우 다른 탐색 속성이 다른 속성의 매핑 정보를 알지 못합니다.
관련 클래스의 해당 탐색 속성 이름이 해당 매개 변수로 필요합니다.
이것은 동일한 유형의 다른 엔티티와 관계가있는 엔티티에 대해서도 사용될 수 있으며 재귀 관계를 형성합니다.
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
public class TreeNode
{
[Key]
public int ID { get; set; }
public int ParentID { get; set; }
...
[ForeignKey("ParentID")]
public TreeNode ParentNode { get; set; }
[InverseProperty("ParentNode")]
public virtual ICollection<TreeNode> ChildNodes { get; set; }
}
ForeignKey
특성을 사용하여 테이블의 외래 키에 사용되는 열을 지정합니다. 첫 번째 예에서 Employee
클래스의 두 속성에는 ForeignKey
를 정의하기 위해 ForeignKey
특성이 적용되었을 수 있습니다.
[ComplexType] 특성
using System.ComponentModel.DataAnnotations.Schema;
[ComplexType]
public class BlogDetails
{
public DateTime? DateCreated { get; set; }
[MaxLength(250)]
public string Description { get; set; }
}
public class Blog
{
...
public BlogDetails BlogDetail { get; set; }
}
Entity Framework에서 클래스를 복합 형식으로 표시합니다.
복잡한 유형 (또는 도메인 기반 디자인에서 값 개체 )은 자체적으로 추적 할 수 없지만 개체의 일부로 추적됩니다. 따라서 BlogDetails에 키 속성이없는 이유가 여기에 있습니다.
여러 클래스에 걸쳐 도메인 엔터티를 설명하고 해당 클래스를 완전한 엔터티로 계층화 할 때 유용 할 수 있습니다.