这个示例同时包含了一对多,如下4个类:
部门类 Department
员工类 Employee
项目类 Project
部门和员工是一对多关系
项目和员工是多对多关系
代码如下:
部门类:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel.DataAnnotations; namespace EFLabCodeFirst { [Table("Departs")] public class Department { [Key] [DatabaseGenerated( System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.None)] [Column("DEPART_ID")] [MaxLength(6)] public string DepartID { get; set; } [Column("DEPART_NAME")] [MaxLength(16)] public string DepartName { get; set; } [Column("DEPART_BUILD_TIME")] public DateTime? DepartBuildTime { get; set; } /// <summary> /// 一个部门有多个员工 /// </summary> public virtual ICollection<Employee> Employees{get;set;} } }
项目类:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel.DataAnnotations; namespace EFLabCodeFirst { /// <summary> /// 项目,一个项目可以有多个员工参与 /// </summary> [Table("Projects")] public class Project { /// <summary> /// 项目编号,按照Code First约定会生成标识列 /// </summary> public int? ProjectId { get; set; } /// <summary> /// 项目名称 /// </summary> [Required] [MaxLength(32)] public string ProjectName { get; set; } /// <summary> /// 项目启动时间 /// </summary> public DateTime? ProjectStartTime { get; set; } /// <summary> /// 参与此项目的员工的集合 /// </summary> public virtual ICollection<Employee> Employees { get; set; } } }
员工类:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel.DataAnnotations; namespace EFLabCodeFirst { /// <summary> /// 员工,一个员工可以参与多个项目 /// </summary> [Table("Employees")] public class Employee { [Key] [DatabaseGenerated( System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.None)] [MaxLength(8)] public string EmployeeID { get; set; } [Column("DEPART_ID")] [MaxLength(6)] public string DepartID { get; set; } /// <summary> /// 一个员工属于一个部门 /// </summary> [ForeignKey("DepartID")] [InverseProperty("Employees")] public virtual Department Department {get;set;} [Required] [MaxLength(8)] public string EmployeeName { get; set; } public int? EmployeeAge { get; set; } /// <summary> /// 当前员工参与的项目的集合 /// </summary> public virtual ICollection<Project> Projects { get; set; } } }
CodeFirstDbContext类:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data.Entity; using System.Data.Objects; using System.ComponentModel.DataAnnotations; namespace EFLabCodeFirst { /// <summary> /// 自定义类必须继承自DbContext,DbContext来自EF4.1的EntiyFramework.dll这个程序集 /// </summary> public class CodeFirstDbContext:DbContext { public DbSet<GameUser> GameUsers { get; set; } public DbSet<GameRole> GameRoles { get; set; } public DbSet<Project> Projects { get; set; } public DbSet<Employee> Employees { get; set; } public CodeFirstDbContext() { } public CodeFirstDbContext(string conn):base(conn) { //是否启用延迟加载: // true: 延迟加载(Lazy Loading):获取实体时不会加载其导航属性,一旦用到导航属性就会自动加载 // false: 直接加载(Eager loading):通过 Include 之类的方法显示加载导航属性,获取实体时会即时加载通过 Include 指定的导航属性 this.Configuration.LazyLoadingEnabled = true; this.Configuration.AutoDetectChangesEnabled = true; //自动监测变化,默认值为 true } /// <summary> /// 实体到数据库结构的映射是通过默认的约定来进行的,如果需要修改的话,有两种方式,分别是:Data Annotations 和 Fluent API // 以下示范通过 Fluent API 来修改实体到数据库结构的映射 /// </summary> /// <param name="modelBuilder"></param> protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<GameRole>() .Property(p => p.GameRoleID) .HasColumnName("GameRoleID")//设置映射的表字段名 .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)//设置映射字段的值生成方式为标识列 .IsRequired();//设置字段值是必须的 modelBuilder.Entity<GameRole>() .Property(p => p.GameRoleName) .HasMaxLength(32)//字段长度 .IsOptional()//字段的值可以为空 .IsUnicode()//字段值类型为nvarchar .IsVariableLength();//字段长度是可变的 modelBuilder.Entity<Project>()//注册一个实体类型为模型的一部分,返回的对象用于配置这个实体 .HasMany<Employee>(p => p.Employees)//从这个实体类型配置一个多关系[此处表明一个项目拥有一个员工对象的集合] .WithMany(e => e.Projects)//配置这个多对多关系的另一端,另一端通过导航属性能够被访问(此处表明一个员工拥有一个项目对象的集合) .Map(m => { //配置用于存储关系的外键字段和表 m.MapLeftKey("ProjectID");//引用的左表字段 m.MapRightKey("EmployeeID");//引用的右表字段 m.ToTable("ProjectEmployee");//中间表 }); base.OnModelCreating(modelBuilder); } } } 测试代码:
static void Demo7() { using(CodeFirstDbContext db = new CodeFirstDbContext()) { //添加项目对象 db.Projects.Add(new Project { ProjectName = "CRM系统", ProjectStartTime = DateTime.Now }); db.Projects.Add(new Project { ProjectName = "HR系统",ProjectStartTime=DateTime.Now}); db.Projects.Add(new Project { ProjectName= "数字触摸屏系统",ProjectStartTime=DateTime.Now }); //保存项目对象 db.SaveChanges(); Project p1 = db.Projects.Where(d => d.ProjectName == "CRM系统").FirstOrDefault(); db.Entry(p1).Reload();//预加载项目对象 //添加员工对象 p1.Employees.Add(new Employee { EmployeeID = "E001",EmployeeName="刘兵",EmployeeAge=22}); p1.Employees.Add(new Employee { EmployeeID = "E002", EmployeeName = "王雪梅", EmployeeAge = 30 }); p1.Employees.Add(new Employee { EmployeeID = "E003", EmployeeName = "张一山", EmployeeAge = 22 }); //保存员工对象及项目对象和员工对象的关系 db.SaveChanges(); } App.config文件配置:
<?xml version="1.0" encoding="utf-8"?> <configuration> <connectionStrings> <add name="CodeFirstDbContext" connectionString="Server=.\sqlexpress;Database=CodeFirst;integrated security=true" providerName="System.Data.SqlClient"/> </connectionStrings> </configuration> 生成的数据结构: