Code First Fluent API,使用流畅API来定义模型映射。
同样使用与上文 Database First 模式相同的例子,假设需要设计一个零售系统,我们先构建一个 Customer 类。
1 public class Customer 2 { 3 public long Id { get; set; } 4 public string Name { get; set; } 5 public string Address { get; set; } 6 public string Phone { get; set; } 7 }
这次没有使用属性来指定对应表名称、主键等。
使用代码创建影射,
1 public class CustomerMap : EntityTypeConfiguration<Customer> 2 { 3 public CustomerMap() 4 { 5 // Primary Key 6 this.HasKey(t => t.Id); 7 8 // Properties 9 this.Property(t => t.Name) 10 .IsRequired() 11 .HasMaxLength(256); 12 13 this.Property(t => t.Phone) 14 .IsRequired() 15 .HasMaxLength(256); 16 17 // Table & Column Mappings 18 this.ToTable("Customer", "STORE"); 19 this.Property(t => t.Id).HasColumnName("Id"); 20 this.Property(t => t.Name).HasColumnName("Name"); 21 this.Property(t => t.Address).HasColumnName("Address"); 22 this.Property(t => t.Phone).HasColumnName("Phone"); 23 24 // Relationships 25 //this.HasRequired(t => t.Status) 26 // .WithMany(t => t.CustomerStatus) 27 // .HasForeignKey(d => d.Status); 28 } 29 }
在上下文对象中覆写OnModelCreating方法来添加影射配置,
1 public class RetailEntities : DbContext 2 { 3 static RetailEntities() 4 { 5 //Database.SetInitializer<RetailEntities>(new CreateDatabaseIfNotExists<RetailEntities>()); 6 //Database.SetInitializer<RetailEntities>(new DropCreateDatabaseAlways<RetailEntities>()); 7 //Database.SetInitializer<RetailEntities>(new DropCreateDatabaseIfModelChanges<RetailEntities>()); 8 Database.SetInitializer<RetailEntities>(null); 9 } 10 11 public RetailEntities() 12 : base("Name=RetailEntities") 13 { 14 } 15 16 public DbSet<Customer> Customers { get; set; } 17 18 protected override void OnModelCreating(DbModelBuilder modelBuilder) 19 { 20 modelBuilder.Configurations.Add(new CustomerMap()); 21 } 22 }
ICustomerRepository接口和实现依然类似,
1 public void InsertCustomer(DomainModels.Customer customer) 2 { 3 using (RETAILContext context = new RETAILContext()) 4 { 5 Customer entity = Mapper.Map<DomainModels.Customer, Customer>(customer); 6 context.Customers.Add(entity); 7 context.SaveChanges(); 8 9 customer.Id = entity.Id; 10 } 11 } 12 13 public void UpdateCustomer(DomainModels.Customer customer) 14 { 15 using (RETAILContext context = new RETAILContext()) 16 { 17 Customer entity = context.Customers.AsQueryable().Single(c => c.Id == customer.Id); 18 19 entity.Name = customer.Name; 20 entity.Address = customer.Address; 21 entity.Phone = customer.Phone; 22 23 context.SaveChanges(); 24 } 25 }
同样的测试代码,
1 ICustomerRepository customerRepository = new CustomerRepository(); 2 3 // =============== 增 =============== 4 Console.ForegroundColor = ConsoleColor.DarkRed; 5 6 DomainModels.Customer customer1 = new DomainModels.Customer() 7 { 8 Name = "Dennis Gao", 9 Address = "Beijing", 10 Phone = "18888888888", 11 }; 12 customerRepository.InsertCustomer(customer1); 13 Console.WriteLine(customer1);
当然,你可能觉得手工写影射代码还是比较繁琐,如果已有部分数据表结构,希望反向生成代码,可使用工具 Entity Framework Power Tools 来生成。
Entity Framework Power Tools 拯救程序员啊。
完整代码和索引
EntityFramework用法探索系列