EF Code-First - Ánh xạ thuộc tính
Ánh xạ thuộc tính bằng Fluent API
Fluent API có thể được sử dụng để cấu hình các thuộc tính của thực thể để ánh xạ nó với cột db.
Sử dụng Fluent API, bạn có thể thay đổi tên cột, kiểu dữ liệu, kích thước, Null hoặc NotNull, PrimaryKey, ForeignKey, cột concurrency, v.v.
Chúng tôi sẽ cấu hình các lớp thực thể sau.
public class Student
{
public int StudentKey { get; set; }
public string StudentName { get; set; }
public DateTime DateOfBirth { get; set; }
public byte[] Photo { get; set; }
public decimal Height { get; set; }
public float Weight { get; set; }
public Standard Standard { get; set; }
}
public class Standard
{
public int StandardKey { get; set; }
public string StandardName { get; set; }
public ICollection<Student> Students { get; set; }
}
Cấu hình khóa chính và khóa chính tổng hợp
Các lớp thực thể của chúng tôi ở trên, không tuân theo quy ước Code First cho khóa chính vì chúng không có thuộc tính Id hoặc {Tên lớp} + "Id".
Vì vậy, bạn có thể cấu hình thuộc tính khóa bằng phương thức HasKey()
như dưới đây. Hãy nhớ rằng modelBuilder.Entity<TEntity>()
trả về đối tượng EntityTypeConfiguration
.
public class SchoolContext: DbContext
{
public SchoolDBContext(): base()
{
}
public DbSet<Student> Students { get; set; }
public DbSet<Standard> Standards { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//Configure primary key
modelBuilder.Entity<Student>().HasKey<int>(s => s.StudentKey);
modelBuilder.Entity<Standard>().HasKey<int>(s => s.StandardKey);
//Configure composite primary key
modelBuilder.Entity<Student>().HasKey<int>(s => new
{
s.StudentKey,
s.StudentName
});
}
}
Cấu hình tên cột, kiểu dữ liệu và thứ tự
Quy ước Code First mặc định tạo một cột cho một thuộc tính có cùng tên, thứ tự và kiểu dữ liệu. Bạn có thể ghi đè quy ước này, như ví dụ bên dưới.
public class SchoolContext: DbContext
{
public SchoolDBContext(): base()
{
}
public DbSet<Student> Students { get; set; }
public DbSet<Standard> Standards { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//Configure Column
modelBuilder.Entity<Student>()
.Property(p => p.DateOfBirth)
.HasColumnName("DoB")
.HasColumnOrder(3)
.HasColumnType("datetime2");
}
}
Như bạn có thể thấy trong ví dụ trên, phương thức Property()
được sử dụng để cấu hình một thuộc tính của một thực thể.
Phương thức HasColumnName()
được sử dụng để thay đổi tên cột của thuộc tính DateOfBirth
. Ngoài ra, các phương thức HasColumnOrder()
và HasColumnType()
thay đổi thứ tự và kiểu dữ liệu của cột tương ứng.
Phương thức modelBuilder.Entity<TEntity>() .Property(expression)
cho phép bạn sử dụng các phương thức khác nhau để định cấu hình một thuộc tính cụ thể, như hình ảnh bên dưới.
Cấu hình cột Null hoặc NotNull
EF 6 API sẽ tạo cột NotNull cho thuộc tính kiểu dữ liệu nguyên thủy vì kiểu dữ liệu nguyên thủy không thể Null trừ khi được đánh dấu là nullable bằng cách sử dụng dấu ?
hoặc kiểu Nullable<T>
.
Sử dụng phương thức IsOptional()
để tạo một cột nullable cho một thuộc tính. Theo cách tương tự, sử dụng phương thức IsRequired()
để tạo cột NotNull.
public class SchoolContext: DbContext
{
public SchoolDBContext(): base()
{
}
public DbSet<Student> Students { get; set; }
public DbSet<Standard> Standards { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//Configure Null Column
modelBuilder.Entity<Student>()
.Property(p => p.Heigth)
.IsOptional();
//Configure NotNull Column
modelBuilder.Entity<Student>()
.Property(p => p.Weight)
.IsRequired();
}
}
Cấu hình kích thước cột
Code First sẽ đặt kích thước tối đa của kiểu dữ liệu cho một cột. Bạn có thể ghi đè quy ước này, như ví dụ bên dưới.
public class SchoolContext: DbContext
{
public SchoolDBContext(): base()
{
}
public DbSet<Student> Students { get; set; }
public DbSet<Standard> Standards { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//Set StudentName column size to 50
modelBuilder.Entity<Student>()
.Property(p => p.StudentName)
.HasMaxLength(50);
//Set StudentName column size to 50 and change datatype to nchar
//IsFixedLength() change datatype from nvarchar to nchar
modelBuilder.Entity<Student>()
.Property(p => p.StudentName)
.HasMaxLength(50).IsFixedLength();
//Set size decimal(2,2)
modelBuilder.Entity<Student>()
.Property(p => p.Height)
.HasPrecision(2, 2);
}
}
Như bạn có thể thấy trong ví dụ trên, chúng tôi đã sử dụng phương thức HasMaxLength()
để thiết lập kích thước của một cột.
Phương thức IsFixedLength()
chuyển kiểu nvarchar thành kiểu nchar. Theo cách tương tự, phương thức HasPrecision()
cũng thay đổi độ chính xác của cột decimal.
Cấu hình cột concurrency
Bạn có thể cấu hình một thuộc tính dưới dạng cột concurrency (chống xung đột) bằng phương thức ConcurrencyToken()
, như được trình bày bên dưới.
public class SchoolContext: DbContext
{
public SchoolDBContext(): base()
{
}
public DbSet<Student> Students { get; set; }
public DbSet<Standard> Standards { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//Set StudentName as concurrency column
modelBuilder.Entity<Student>()
.Property(p => p.StudentName)
.IsConcurrencyToken();
}
}
Như bạn đã thấy ở trên, chúng tôi thiết lập cột StudentName
là cột concurrency để nó sẽ được thêm trong mệnh đề where trong các lệnh UPDATE và DELETE.
Bạn cũng có thể sử dụng phương thức IsRowVersion()
cho thuộc tính kiểu byte[]
để biến nó thành một cột concurrency.