返回首页
当前位置: 主页 > 网络编程 > .Net实例教程 >

如何在EF中更新模型之间的关系

时间:2016-10-28 22:12来源:知行网www.zhixing123.cn 编辑:麦田守望者

一  EF中模型之间关系的分类

EF中模型之间的关系可以分为4种:1对1,1对多,多对1,多对多。但是,在更新模型间关系时,可以归纳为两种情况:1对1与1对多。
对于多对1关系而言,假设如下场景:一个班级可以有多个学生,那么对于学生而言,学生与班级之间就是多对1的关系。但是,具体到每一个学生的时候,他在同一时间内只能在一个班级中,也就是说他与班级实际上是1对1的。因此,多对1关系在更新时可以当作1对1的情况来更新。
同理,对于多对多关系而言,在更新时可以当作1对多的情况来更新。所以更新模型间关系时只需要处理1对1与1对多两种情况即可。

二  1对1情况时的更新操作

假设现在有两个模型类:student学生类和class班级类,学生和班级之间是多对1的关系,现在有一个学生studentA要将他的班级变更为classB,我们可以按classB是否已经存在于数据库中分成两种情况来操作:
l  classB还没有在数据库中建立
在这种情况下直接更新studentA就可以了,代码如下所示:
studentA.class=classB;
using(Context context=new Context())
{
    context.Entry<student>(studentA).State = EntityState.Modified;
    context.SaveChanges();
}
这样会自动创建classB并将studentA与classB关联起来。
l  classB在数据库中已经建立了
在这种情况下需要手动将studentA与数据库中已经存在的classB关联起来,代码如下:
studentA.class=classB;
using(Context context=new Context())
{
class classBinDatabase=context.classes.FirstOrDefault<class>(x => x.ID == studentA.class.ID);
    studentA.class= classBinDatabase;
context.Entry<student>(studentA).State = EntityState.Modified;
context.SaveChanges();
}
也可以通过判断classBinDatabase是否为null将以上两种情况合并成以下代码:
studentA.class=classB;
using(Context context=new Context())
{
class classBinDatabase=context.classes.FirstOrDefault<class>(x => x.ID == studentA.class.ID);
if(classBinDatabase!=null)
{
        studentA.class= classBinDatabase;
}
context.Entry<student>(studentA).State = EntityState.Modified;
context.SaveChanges();
}

三  多对1情况时的更新操作

假设现在有两个模型类:teacher教师类和class班级类,教师和班级之间是多对多的关系,现在有一个教师teacherA要更新他所教的班级列表,他可能在不再教某些班级的同时又新教了某些班级,更新操作的步骤如下:

3.1    获取数据库上下文

Context context=new Context();

3.2    获取数据库中保存的teacherA的信息

var existingTeacher= context.teacher.Include(x => x.classes).Where(x => x.ID == teacherA.ID).FirstOrDefault<teacher>();

3.3    获取不再教的班级列表

var deletedClasses = existingTeacher.classes.Except(teacherA.classes, x => x.ID).ToList<class>();

3.4    获取新教的班级列表

var addedClasses = teacherA.classes.Except(existingTeacher.classes, x => x.ID).ToList<class>();

3.5       获取数据库中已经存在的所有班级列表

var existingClasses = context.classes.ToList<class>();

3.6       获取新教班级列表中在数据库已存在的班级列表

var existingAddedClasses = addedClasses.Where(x => existingClasses.Any(y => y.ID == x.ID)).ToList< class >();

3.7       将不再教的班级从数据库中的teacherA的班级列表中移除

deletedClasses.ForEach(x => teacherA.classes.Remove(x));

3.8       将新教班级列表中在数据库已存在的班级添加到teacherA的班级列表中

foreach (var c in existingAddedClasses)
{
class dbClass = context.classes.FirstOrDefault(x => x.ID == c.ID);
    existingTeacher.classes.Add(dbClass);
}

3.9       更新数据库

context.SaveChanges();
完整代码如下所示:
using(Context context=new Context())
{
var existingTeacher= context.teacher.Include(x => x.classes).Where(x => x.ID == teacherA.ID).FirstOrDefault<teacher>();
var deletedClasses = existingTeacher.classes.Except(teacherA.classes, x => x.ID).ToList<class>();
var addedClasses = teacherA.classes.Except(existingTeacher.classes, x => x.ID).ToList<class>();
var existingClasses = context.classes.ToList<class>();
var existingAddedClasses = addedClasses.Where(x => existingClasses.Any(y => y.ID == x.ID)).ToList< class >();
deletedClasses.ForEach(x => teacherA.classes.Remove(x));
foreach (var c in existingAddedClasses)
{
class dbClass = context.classes.FirstOrDefault(x => x.ID == c.ID);
    existingTeacher.classes.Add(dbClass);
}
context.SaveChanges();
}
在上面的代码中使用了一个自定义方法Except,是对System.Collections.Generic的扩展,它的定义如下:
public static IEnumerable<T> Except<T, TKey>(this IEnumerable<T> items, IEnumerable<T> other, Func<T, TKey> getKey)
{
    return from item in items
           join otherItem in other on getKey(item)
           equals getKey(otherItem) into tempItems
           from temp in tempItems.DefaultIfEmpty()
           where ReferenceEquals(null, temp) || temp.Equals(default(T))
           select item;
}
以上就是在EF中更新模型之间的关系方法。
顶一下
(0)
0%
踩一下
(0)
0%
标签(Tag):EntityFramework
------分隔线----------------------------
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
验证码:点击我更换图片