EF手动将实体列表附加到父实体

时间:2018-08-08 03:12:23

标签: asp.net entity-framework

class Student{
public string Name {get; set;}

public EntityCollection<Info> Infos {get; set;}
}

class Info{
public string Title {get; set;}
public Student Student {get; set;}
}

我有两个这样的实体。首先,我将查询一个学生实体

var student = db.Students.FirstOrDefault(s => s.StudentId = 1);

然后我在另一个查询中查询该学生的信息列表

var infos = from c in db.Info where c.StudentId = 1 and ....

如果我遍历信息并将其手动添加到student.Infos中,将导致插入新行

foreach(info in infos){
student.Infos.Add(info);
}

如何在db.SaveChanges()时将信息列表附加到学生实体中而不在Info表中插入新行。喜欢

student.Infos = infos 

1 个答案:

答案 0 :(得分:0)

使用导航属性时,

EF会在幕后为您完成工作。它不仅是单独加载数据的数据层,而且还设置了数据之间的关系,并且能够一次命中(急切加载)或按需(延迟加载)加载相关数据的整个对象图。 / p>

首先:您可以将信息集合更新为ICollection<Info>List<Info>。我之所以选择List<Info>是因为我通常使用.AddRange()。另外,将其标记为虚拟以启用EF代理和延迟加载。

从那里,您可以使用以下方法访问学生的信息:

var student = db.Students.Include(s => s.Infos).SingleOrDefault(s => s.StudentId = 1);

这将渴望为所选学生加载信息。无需单独加载它们。

如果不使用.include(..),则仍可以访问信息(前提是DbContext仍在范围内),尽管这将触发其他SQL调用来加载信息。 (延迟加载)

在加载要发送到DbContext范围之外的数据(例如从API调用返回或发送到视图的数据)时,建议仅使用各个实体所需的字段组成DTO或ViewModel,然后执行.Select()来填充它们,并返回DTO而不是实体。这样可以避免在处理DbContext之后出现延迟加载调用的问题,以及避免由于序列化等触发延迟加载而导致意外的性能问题。