关于Entity Framwork之前已经在EntityFramework系列内容中介绍了两篇。码农们应该都知道数据库理论中的多样性关系,即一对一关系、一对多关系、多对多关系,今天我们就来介绍一下用Entity Framework的CodeFirst如何实现。以下接着使用之前的源码示例继续进行。
一对一关系
这种关系,不常用到,本身在数据库设计中也不常用,遇到这种情况一般就一个表记录完事儿。但是如果遇到一个实体存在可选数据,那么就可以选择这种一对一的关系设计。
接着之前代码示例,我们创建一个Student实体。一个用户可以是学生,也可以不是学生,我们把用户的学生信息单独记录在Student表中。
public class Student
{
///
/// 用户ID
///
public int UserId { get; set; }
///
/// 用户
///
public virtual User User { get; set; }
///
/// 学校名
///
public string CollegeName { get; set; }
///
/// 入学时间
///
public DateTime EnrollmentDate { get; set; }
}
因为一对一关系,所以我们需要在之前的User实体中也添加一行学生对象的记录(这里使用virtual关键字的目的是什么呢?没错,懒加载):
public virtual Student Student { get; set; }
然后我们需要创建一个学生伙伴类,来指定主键、外键,设置属性等。然后在数据库上下文的OnModelCreating方法使用学生伙伴类。
public class StudentMap : EntityTypeConfiguration
{
public StudentMap()
{
//设置外键关系
HasRequired(s => s.User).WithOptional(p => p.Student);
//指定主键
HasKey(s => s.UserId);
//设置学校名的属性(字符长度50,不可为空)
Property(s => s.CollegeName).HasMaxLength(50).IsRequired();
}
}
Main方法中,创建数据库的代码如下:
using (var context = new TestContext())
{
//如果数据库不存在时则创建
context.Database.CreateIfNotExists();
var student = new Student
{
CollegeName = "XX大学",
EnrollmentDate = DateTime.Parse("2000-11-11"),
User = new User
{
Name = "张三",
BirthDay= DateTime.Parse("1980-01-01")
}
};
context.Students.Add(student);
context.SaveChanges();
}
编译运行,你就能看到数据库里的表结构以及示例数据。
一对一关系就介绍到这里。接下来介绍一对多关系。
一对多关系
继续针对User实体,实际场景中,用户一般有分角色:管理员用户角色、普通用户角色等。这里只用两个角色来做示例,先介绍一个用户只有一个角色、一个角色可以包含多个用户的情况,即设定用户角色为一对多关系。用户角色的多对多关系,再后面进行介绍。
首先,添加一个用户角色实体类:
public class UserActor
{
public int UserActorId{ get; set; }
public string ActorName { get; set; }
//集合属性。表示一个角色可以有多个用户。(懒加载)
public virtual ICollection Users { get; set; }
}
接下来,修改之前创建的用户实体类:
public class User
{
public int UserId { get; set; }
public string Name { get; set; }
public DateTime BirthDay { get; set; }
public int? ActorId { get; set; }
public virtual UserActor UserActor { get; set; }
}
此处使用了可空类型字段,说明外键可为null。
接下来创建用户角色的伙伴类:
public class UserActorMap : EntityTypeConfiguration
{
public UserActorMap()
{
HasMany(dt => dt.Users)
.WithOptional(d => d.UserActor) //指定实体关系
.HasForeignKey(d => d.ActorId) //指定外键
.WillCascadeOnDelete(false); //指定约束的删除规则
}
}
Main方法中,创建数据库的代码如下:
using (var context = new TestContext())
{
//如果数据库不存在时则创建
context.Database.CreateIfNotExists();
var userActor = new UserActor
{
ActorName = "管理员",
Users = new List { new User { Name = "张三", BirthDay = new DateTime(2001, 2, 2) } }
};
var userActor2 = new UserActor
{
ActorName = "普通用户",
Users = new List { new User { Name = "李四", BirthDay = new DateTime(1998, 5, 5) } }
};
context.UserActors.Add(userActor);
context.UserActors.Add(userActor2);
context.SaveChanges();
}
不要忘了在Context类中添加UserActor的DbSet,还有在OnModelCreating上添加UserActorMap的配置类。
编译运行,你就能看到数据库里的表结构以及示例数据。
一对多关系就介绍到这里。接下来介绍多对多关系。
多对多关系
接下来介绍用户角色的多对多关系。
参考一对多关系,不难想出如何修改一对多的用户角色关系为多对多的用户角色关系。
修改用户实体:
public class User
{
public User()
{
UserActors = new HashSet();
}
public int UserId { get; set; }
public string Name { get; set; }
public DateTime BirthDay { get; set; }
//public int? ActorId { get; set; }
//public virtual UserActor UserActor { get; set; }
public virtual ICollection UserActors { get; set; }
}
同时我在用户角色实体中也添加了构造函数,用来初始化用户集合。
public UserActor()
{
Users = new HashSet();
}
修改用户角色伙伴类:
public UserActorMap()
{
//HasMany(dt => dt.Users)
// .WithOptional(d => d.UserActor) //指定实体关系
// .HasForeignKey(d => d.ActorId) //指定外键
// .WillCascadeOnDelete(false); //指定约束的删除规则
HasMany(p => p.Users)
.WithMany(c => c.UserActors)
.Map(m =>
{
m.MapLeftKey("UserId");
m.MapRightKey("UserActorId");
});
}
Main方法中,创建数据库的代码如下:
using (var context = new TestContext())
{
//如果数据库不存在时则创建
context.Database.CreateIfNotExists();
var user = new User
{
Name = "张三",
BirthDay = new DateTime(2001, 2, 2)
};
var user2 = new User
{
Name = "李四",
BirthDay = new DateTime(1998, 5, 5)
};
context.Users.Add(user);
context.Users.Add(user2);
var userActor = new UserActor
{
ActorName = "普通用户"
};
userActor.Users.Add(user);
context.UserActors.Add(userActor);
context.SaveChanges();
}
编译运行,你就能看到数据库里的表结构以及示例数据。
从数据库中,可以看到Entity Framework在处理多对多关系的时候,会自动创建一个中间表(比如上面示例,数据库中创建的UserActorUsers表),用来记录多对多的关系。该中间表的名称,可以在伙伴类中设定。
以上就是今天介绍的Entity Framework管理三种实体关系的源码示例及简单说明。
下期预告:【EntityFramework系列】入门湿货(三)数据迁移。
领取专属 10元无门槛券
私享最新 技术干货