linq实体框架包括奇怪的行为

时间:2015-03-13 11:35:48

标签: linq entity-framework c#-4.0

当我没有明确地使用include作为导航属性时,我遇到了linq查询的问题。

---Task entity model ----
...
 public Project Project { get; set; }
 public TaskType TaskType { get; set; }
...

var tasks = db.Tasks
        .Where(t => (t.Project.ProjectId == project.ProjectId))


foreach (Task t in tasks)
{
 // for some items t.TaskType is null   


// I have noticed that when t.TaskType.Id 
// is different to the first one in the loop then only the next different 
// tasktype is null

} 


// however when using 
var tasks = db.Tasks.Include(t=>t.TaskType)
        .Where(t => (t.Project.ProjectId == project.ProjectId))          
// tasktype is always there (where as without the include in some tasks it  does not extract the tasktype)

使用.Include解决了我的问题,但我想理解为什么它会像这样。

2 个答案:

答案 0 :(得分:0)

如果在EF中使用Eager Loading,则导航属性不会加载根对象。 Include方法指示EF,该导航属性应该加载您的根对象。

加载Lazy加载导航属性时,调用此属性时,如果使用延迟加载,则不需要Include方法。

更多here

答案 1 :(得分:0)

我认为你所寻找的是延迟加载相关实体。为此,您需要将导航属性指定为virtual。从page

开始
  

延迟加载是实体或集合的过程   第一次从数据库自动加载实体   访问涉及实体/实体的属性。使用时   POCO实体类型,延迟加载是通过创建实例来实现的   派生代理类型,然后重写虚拟属性以添加   装钩。

在导航属性中指定virtual关键字时,EF会在运行时为您的实体类创建动态代理。这些代理类负责相关实体的延迟加载行为。如果没有虚拟,则不支持延迟加载,并且导航属性上的null为空。所以你需要这样做:

public class Task
{
   //...
   public virtual Project Project { get; set; }
   public virtual TaskType TaskType { get; set; }
{

在这个link中,您将找到支持延迟加载所需的所有要求。

使用Include方法,您可以将相关实体作为查询的一部分加载。