博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
EF基础知识小记五(一对多、多对多处理)
阅读量:6188 次
发布时间:2019-06-21

本文共 6285 字,大约阅读时间需要 20 分钟。

本文主要讲EF一对多关系和多对多关系的建立

一、模型设计器

1、一对多关系

右键设计器新增关联

导航属性和外键属性可修改

2、多对多关系

右键设计器新增关联

模型设计完毕之后,根据右键设计器根据模型生成数据库,就能生成对应的表之间的一对多和多对多关联

 

二、代码层面

建表语句如下:

--建表脚本create table Student(    Id int not null,    Name varchar(30) not null,    Age int not null)create table Teacher(    Id int not null,    Name varchar(30) not null,    Age int not null)create table StudentTeacher(    StudentId int not null,    TeacherId int not null)create table InfoCard(    Id int not null,    [Money] int not null,    StudentId int not null)

添加常规主键约束,代码如下:

--单主键约束alter table Student add constraint [PK_People]primary key clustered (Id Asc)alter table InfoCard add constraint [PK_InfoCard]primary key clustered (Id Asc)alter table Teacher add constraint [PK_Teacher]primary key clustered (Id Asc)

 

1、一对多(通过外键)

--但外键约束(一对多)alter table InfoCard add constraint [FK_InfoCard_Student]foreign key (StudentId) references Student (Id) on delete no action on update no action

 

2、多对多(中间表双主键双外键)

--双主键约束(多对多)alter table StudentTeacher add constraint [PK_StudentTeacher]primary key clustered (StudentId,TeacherId Asc)--双外键约束(多对多)alter table StudentTeacheradd constraint [FK_StudentTeacher_Student]foreign key (StudentId) references Student (Id) on delete no action on update no action --级联更新级联删除alter table StudentTeacher add constraint [FK_StudentTeacher_Teacher]foreign key (TeacherId) references Teacher (Id) on delete no action on update no action

生成对应的一对多和多对多关联的表之后,根据数据库生成模型就能生成对应的模型

 

三、多对多无载荷

根据上面的建表语言,我们能得出Teacher表和Student表在数据库中的关系如下图:

数据库关系图:

在模型设计器中的关系如下图:

模型设计图:

 

观察二图的区别,发现数据库表关系图中的StudentTeacher(链接表)没有出现在模型设计器中。原因如下:

因为链接表没有标量属性(没有载荷),实体框架认为它存在的唯一价值就是联结Teacher和Student,没有标量属性的联结表,在各自的实体中将以ICollection集合的形式出现.

当然如果链接表有标量属性,那么模型设计器就会创建一个完成的类来表示链接表。

 

四、多对多无载荷增改

// 添加demo            using (var context = new EF6RecipeEntities())            {                //给一个Teacher添加几个Student                var teacher1 = new Teacher                {                    Id=1,                    Name = "张老师",                    Age = 30                };                var stu1 = new Student                {                    Id = 2,                    Name = "张三",                    Age = 20                };                var stu2 = new Student                {                    Id = 3,                    Name = "李四",                    Age = 21                };                context.Teacher.Add(teacher1);//添加老师teacher1                teacher1.Student.Add(stu1);//给老师添加学生stu1                teacher1.Student.Add(stu2);//给老师添加学生stu2                //给一个Student添加几个Teacher                var stu3 = new Student                {                    Id = 4,                    Name = "小超",                    Age = 23                };                var t2 = new Teacher                {                    Id = 5,                    Name = "王老师",                    Age = 33                };                var t3 = new Teacher                {                    Id = 6,                    Name = "赵老师",                    Age = 36                };                context.Student.Add(stu3);                stu3.Teacher.Add(t2);                stu3.Teacher.Add(t3);                context.SaveChanges();            }            //遍历所有老师下面的所有学生            using (var context = new EF6RecipeEntities())            {                DbSet
ts = context.Teacher; foreach (var t in ts) { Console.WriteLine("姓名:{0},年龄:{1},职位:{2},其管理的学生如下:", t.Name, t.Age, "老师"); var stus = t.Student; foreach (var s in stus) { Console.WriteLine("姓名:{0},年龄:{1},职位:{2}", s.Name, s.Age, "学生"); } Console.WriteLine(); } } Console.ReadKey();

 

五、多对多有载荷

上面学生和老师的例子并不能很好的说明多对多有载荷的问题,所以换成订单和产品,所以链接表将会产生一个订单数量的载荷(也就是链接表多了一个标量属性),

模型设计图如下:

有载荷的多对多关系比无载荷的多对多关系更加的简介明了。因为实体框架不支持在关联上附加载荷,所以有载荷的联结将会生成一个新的实体.

因为这个附加的载荷,Order需要通过OrderItem来获取与其关联的Product的项.

 

六、多对多有载荷增查

//添加            using (var context = new EF6RecipeEntities())            {                var product = new Product                {                    Id = 1,                    Desc = "面包",                    Price = 10                };                var order = new Order                {                    Id = 10,                    OrderDate = DateTime.Now                };                var orderItem1 = new OrderItem                {                    Order = order,                    Product = product,                    Count = 1                };                product = new Product                {                    Id = 2,                    Desc = "牛奶",                    Price = 11                };                var orderItem2 = new OrderItem                {                    Order = order,                    Product = product,                    Count = 2                };                product = new Product                {                     Id = 3,                    Desc = "牛奶面包",                    Price = 11                };                var orderItem3 = new OrderItem                {                    Order = order,                    Product = product,                    Count = 1                };                context.OrderItems.Add(orderItem1);                context.OrderItems.Add(orderItem2);                context.OrderItems.Add(orderItem3);                context.SaveChanges();            }            //遍历            using (var context = new EF6RecipeEntities())            {                foreach (var order in context.Orders)                {                    Console.WriteLine("订单编号:{0},下单日期:{1},订单详情如下:",order.Id,order.OrderDate.ToShortDateString());                    foreach (var oi in order.OrderItem)                    {                        Console.WriteLine("产品Id:{0},产品描述:{1},产品数量:{2},产品价格:{3}", oi.Product.Id,oi.Product.Desc,oi.Count,oi.Product.Price);                    }                    Console.WriteLine();                }            }            Console.ReadKey();

 

 七、关于使用多对多有载荷还是多对多无载荷的意见

如果你有一个无载荷的多对多关系时,你可以考虑通过增加一标识列将其改变为有载荷的多对多关系。当你导入表到你的模型时,你将得到两个包含一对多关系的实体,这意味着,你的代码为将来有可能出现的多载荷做好了准备。增加一整型标识列的代价通常很小,但给模型带来了更大的灵活性。

转载于:https://www.cnblogs.com/GreenLeaves/p/7647178.html

你可能感兴趣的文章
activemq 搭建2
查看>>
Linux安装及升级jdk1.8
查看>>
ZABBIX 4.0 安装过程记录
查看>>
我的友情链接
查看>>
【备份】golang开发环境搭建
查看>>
Python学习-4天--字典的操作
查看>>
Spring 框架 执行SQL getJdbcTemplate().query update 用法
查看>>
javascript对象简介
查看>>
thinkphp 中英文语言包
查看>>
nmake命令行编译Qt项目
查看>>
数据库的varchar长度的限制以及对性能是否有影响
查看>>
我的友情链接
查看>>
Oracle软件安装及手工建库
查看>>
Python NLP完整项目实战教程(1)
查看>>
repeater没有数据显示暂无数据,无记录
查看>>
快速测试UTF8编码的文件是不是加了BOM,不限PHP
查看>>
Android APK XML解析与反编译方法
查看>>
Android 自定义组合控件 简单导航栏
查看>>
深入理解javascript原型和闭包系列
查看>>
有道词典在谷歌Chrome浏览器中无法取词的解决方法
查看>>