您的位置:首页 > 其它

Entity Framework使用建模之Code First 多对多

2011-11-28 18:08 204 查看
这个示例同时包含了一对多,如下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>


生成的数据结构:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: