EF Code-First - Ánh xạ thực thể

Ánh xạ thực thể bằng Fluent API

Fluent API có thể được sử dụng để định cấu hình một thực thể để ánh xạ nó với bảng cơ sở dữ liệu, lược đồ mặc định, v.v.

Cấu hình lược đồ mặc định

Đầu tiên, hãy cấu hình một lược đồ mặc định cho các bảng trong cơ sở dữ liệu. Tuy nhiên, bạn có thể thay đổi lược đồ trong khi tạo các bảng riêng lẻ.

Ví dụ sau đặt lược đồ Admin làm lược đồ mặc định. Tất cả các đối tượng cơ sở dữ liệu sẽ được tạo trong lược đồ Quản trị trừ khi bạn chỉ định rõ ràng một lược đồ khác.

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 default schema
        modelBuilder.HasDefaultSchema("Admin");
    }
}

Ánh xạ thực thể vào bảng

Code First sẽ tạo các bảng cơ sở dữ liệu với tên của các thuộc tính DbSet trong lớp Context, trong trường hợp này là StudentsStandards.

Bạn có thể ghi đè quy ước này và đặt tên bảng khác với các thuộc tính DbSet, như ví dụ ở bên dưới.

namespace CodeFirst_FluentAPI_Tutorials
{
    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 default schema
            modelBuilder.HasDefaultSchema("Admin");
                    
            //Map entity to table
            modelBuilder.Entity<Student>().ToTable("StudentInfo");
            modelBuilder.Entity<Standard>().ToTable("StandardInfo","dbo");
        }
    }
}

Như bạn có thể thấy trong ví dụ trên, chúng ta bắt đầu với phương thức Entity<TEntity>(). Hầu như bạn sẽ phải bắt đầu với phương thức Entity<TEntity>() để định cấu hình bằng Fluent API.

Chúng tôi đã sử dụng phương thức ToTable() để ánh xạ thực thể Student vào bảng StudentInfo và thực thể Standard vào bảng StandardInfo.

Lưu ý rằng bảng StudentInfo nằm trong lược đồ Admin và bảng StandardInfo nằm trong lược đồ dbo vì chúng tôi đã chỉ định lượng đồ mặc định là Admin và chỉ định lược đồ dbo cho bảng StandardInfo.

table mapping with fluent api Entity Framework code-first


Ánh xạ thực thể vào nhiều bảng

Ví dụ sau đây minh họa cách ánh xạ thực thể Student vào nhiều bảng trong cơ sở dữ liệu.

namespace CodeFirst_FluentAPI_Tutorials
{
    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)
        {
            modelBuilder.Entity<Student>().Map(m =>
            {
                m.Properties(p => new 
                { 
                    p.StudentId, 
                    p.StudentName
                });
                m.ToTable("StudentInfo");
            }).Map(m => 
            {
                m.Properties(p => new 
                { 
                    p.StudentId, 
                    p.Height, 
                    p.Weight, 
                    p.Photo, 
                    p.DateOfBirth
                });
                m.ToTable("StudentInfoDetail");
            });

            modelBuilder.Entity<Standard>().ToTable("StandardInfo");
        }
    }
}

Như bạn có thể thấy trong ví dụ trên, chúng tôi đã ánh xạ một số thuộc tính của thực thể Student vào bảng StudentInfo và các thuộc tính khác vào bảng StudentInfoDetail bằng phương thức Map().

Do đó, thực thể Student sẽ chia thành hai bảng, như hình dưới đây.

multiple table mapping with fluent api Entity Framework code-first

Phương thức Map() yêu cầu một tham số kiểu delegate. Bạn có thể truyền một delegate Action hoặc biểu thức lambda trong phương thức Map(), như ví dụ bên dưới.

using System.Data.Entity.ModelConfiguration.Configuration;

namespace CodeFirst_FluentAPI_Tutorials
{
    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)
        {
            modelBuilder.Entity<Student>().Map(delegate(EntityMappingConfiguration<Student> studentConfig)
            {
                studentConfig.Properties(p => new 
                { 
                    p.StudentId, 
                    p.StudentName 
                });
                studentConfig.ToTable("StudentInfo");
            });

            Action<EntityMappingConfiguration<Student>> studentMapping = m =>
            {
                m.Properties(p => new 
                { 
                    p.StudentId, 
                    p.Height, 
                    p.Weight, 
                    p.Photo, 
                    p.DateOfBirth 
                });
                m.ToTable("StudentInfoDetail");
            };
            
            modelBuilder.Entity<Student>().Map(studentMapping);
            modelBuilder.Entity<Standard>().ToTable("StandardInfo");
        }
    }
}