.net 如何在实体框架中查询相关实体(1:N关系)

.net 如何在实体框架中查询相关实体(1:N关系),.net,entity-framework,entity-framework-4,entity-relationship,foreign-key-relationship,.net,Entity Framework,Entity Framework 4,Entity Relationship,Foreign Key Relationship,在场景中获取相关实体的更好方法是什么? 我写了两种方法(请注意类图中的差异)。。。项目具有任务ICollection属性,但成员没有。这两种方法都有效,我想知道哪一种是正确的(更好/更快)。或者,如果没有一个是好的,那么在这些简单的场景中,什么是正确的方法? 代码: 使用(var db=new EntitiesContext()) { //路A Project=db.Projects.Include(“任务”).First(); List projectTasks=project.Tasks.T

在场景中获取相关实体的更好方法是什么?
我写了两种方法(请注意类图中的差异)。。。项目具有任务ICollection属性,但成员没有。这两种方法都有效,我想知道哪一种是正确的(更好/更快)。或者,如果没有一个是好的,那么在这些简单的场景中,什么是正确的方法?
代码:

使用(var db=new EntitiesContext())
{
//路A
Project=db.Projects.Include(“任务”).First();
List projectTasks=project.Tasks.ToList();
count=projectTasks.count;
//B路
Member Member=db.Members.First();
IQueryable memberTasks=从t开始,在db.Tasks中
其中t.AssignedTo.Id==member.Id
选择t;
count=memberTasks.count();
}
我首先使用EF 4.1代码。

顺便说一句:不要太担心结果(计数)。这只是一段测试代码,我当然想在将来查询更多有用的信息。

为什么不使用这个:

project.Tasks.Load();

你为什么不使用这个:

project.Tasks.Load();

方法A更干净,可以一次将相关数据拉入优化的SQL查询。方法B类似于在需要时延迟加载相关数据


当我现在需要数据时,我更喜欢A,当我甚至可能无法访问相关数据时,我更喜欢B,除非用户在程序中采取某些操作。

方法A更干净,并导致优化的SQL查询同时拉入相关数据。方法B类似于在需要时延迟加载相关数据


当我现在需要数据时,我更喜欢A,当我甚至可能无法访问相关数据时,除非用户在程序中采取一些行动。

我认为这两个例子无法比较,因为这两个例子都有各自的用法。如果您具有navigation属性,那么第一种方法肯定是可行的,因为在这种情况下,您将在一次往返中将所有数据返回到数据库。如果没有可用的导航属性,第二种方法很有用。

我认为这两种方法无法比较,因为这两种方法都有各自的用法。如果您具有navigation属性,那么第一种方法肯定是可行的,因为在这种情况下,您将在一次往返中将所有数据返回到数据库。如果没有可用的导航属性,则第二种方法很有用

两种方法都有效,我希望 要知道,哪一个是正确的 (更好/更快)

在常规导航属性中使用Linq to实体是一种方法-数据会自动加入(如果您使用
Include

您的第一个查询当前未针对获取计数进行优化,您可以编写:

count = db.Projects.Include("Tasks").First().Tasks.Count();
否则,您将从数据库加载所有相关的任务实体

两种方法都有效,我希望 要知道,哪一个是正确的 (更好/更快)

在常规导航属性中使用Linq to实体是一种方法-数据会自动加入(如果您使用
Include

您的第一个查询当前未针对获取计数进行优化,您可以编写:

count = db.Projects.Include("Tasks").First().Tasks.Count();

否则,您将从数据库加载所有相关的任务实体。

执行这些查询时,您的性能瓶颈通常属于以下两类之一:

  • 获取太多您不需要的数据
  • 往返数据库的次数过多
  • 您的第一个示例可能会受到第一个示例的影响。如果查看从数据库返回的数据,则项目的所有数据都将在与其相关的每个任务中重复。如果您的项目有大量与之相关的数据,则可能会导致大量开销。如果它相当瘦,就不会花那么多钱

    您的第二个示例创建了获取任务的第二个往返。额外的往返会带来额外的开销,但这意味着总体上会返回较少的重复数据。一次额外的往返可能没什么大不了的,但如果你为多个项目做这件事,你很容易就会有几十次不必要的往返

    因此,根据您的数据的典型外观和您真正希望从中得到什么,决定走哪条路实际上是一种平衡行为。在这种情况下,您最好:

    count = db.Tasks.Count(t => t.AssignedTo.Id == db.Members.FirstOrDefault().Id)
    
    。。。这将创建一个只返回计数的优化查询,没有多余的数据或额外的往返。因此,您可以看到这样的问题的答案将如何真正取决于您试图从数据库中得到什么,确切地说

    回复评论 如果您试图获取与某个内容相关的所有任务,那么您的查询应该只获取任务。有很多方法可以做到这一点:

    var memberTasks = db.Tasks.Where(t => t.AssignedTo.Id == memberId).ToList();
    
    或者(如果您还不知道该会员的ID):

    或者(如果希望同时为多个成员执行任务):

    我可以继续。关键是,所有这些查询都明确地将任务输出,而不必担心成员的数据

    添加额外的数据层也不会有太大的改变:

    var projectTasks = db.Tasks.Where(t => t.Iteration.Project.Id == projectId).ToList();
    

    执行这些查询时,性能瓶颈通常属于以下两类之一:

  • 获取太多您不需要的数据
  • 往返数据库的次数过多
  • 您的第一个示例可能会受到第一个示例的影响。如果查看从数据库返回的数据,则项目的所有数据都将在与其相关的每个任务中重复。如果您的项目有大量与之相关的数据,则可能会导致大量开销。如果它相当瘦,就不会花那么多钱

    您的第二个示例创建了获取任务的第二个往返。额外的往返会带来额外的开销,但这意味着总体上会返回较少的重复数据
    var projectTasks = db.Tasks.Where(t => t.Iteration.Project.Id == projectId).ToList();