这个示例同时包含了一对多,如下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>生成的数据结构:

本文介绍如何使用Entity Framework的Code First方法来建模和处理多对多关系,通过示例展示了部门、员工和项目之间的关系。部门与员工之间是一对多关系,而项目与员工之间是多对多关系,详细代码展示如何定义这些实体及其相互关联。

1万+

被折叠的 条评论
为什么被折叠?



