C# 实体框架:过滤多个“实体”内部数据的最佳实践;“一对多”;关系

C# 实体框架:过滤多个“实体”内部数据的最佳实践;“一对多”;关系,c#,entity-framework,linq,C#,Entity Framework,Linq,在这种情况下: public class Software { [Key] public int Id { get; set; } // Some properties public virtual ICollection<Release> Releases { get; set; } } public class Release { [Key] public int Id {get; set;} public int

在这种情况下:

public class Software
{
    [Key]
    public int Id { get; set; }

    // Some properties

    public virtual ICollection<Release> Releases { get; set; }
}

public class Release
{
    [Key]
    public int Id {get; set;}

    public int Version {get; set;}

    public virtual Software Software {get; set;}
    public virtual ICollection<Report> Reports{get; set;}
}

public class Report
{ 
    [Key]
    public int Id {get; set;}

    // Some properties

    public virtual Release Release {get; set;}
}
或者改用这个查询

from software in context.Softwares
where software.Id == filterId
     from release in software.Releases
     where release.Version == filterVersion
          from report in release.Reports
          select report

最好先对数据进行“筛选”,或者使用实体框架导航属性?

当然,对于我们来说,不可能知道哪个查询执行得最好。这主要取决于每个表中的索引和记录数,这两者都会对执行计划产生巨大影响

但我认为在您的例子中,两个备选方案的查询形状都是相同的。例如,
report.Release.Version
Release.Reports
都将生成内部联接。谓词将以相同的方式生成

因此,这可以归结为个人偏好。 我总是喜欢将我的查询大致结构为

  • 来自
    结果中所需的实体
  • 其中
    过滤器
  • 选择
。。。因为以后很容易添加/删除谓词

这就是:

from report in context.Reports
where report.Release.Version == filterVersion && 
      report.Release.Software.Id == filterId
select report
或者

from software in context.Softwares
where software.Id == filterId
     from release in software.Releases
     where release.Version == filterVersion
          from report in release.Reports
          select report
。。。谓词“到处都是”(嗯,没那么复杂,但你知道我的意思)

但是,如果希望投影包含来自所有实体的数据,则图片会发生变化:

from report in context.Reports
where report.Release.Version == filterVersion && 
      report.Release.Software.Id == filterId
select new
{
    report.Name,
    report.Release.Version,
    report.Release.Software.Id,
    report.Release. ...
}
。。。因为所有虚线引用的可读性比

from software in context.Softwares
where software.Id == filterId
     from release in software.Releases
     where release.Version == filterVersion
          from report in release.Reports
select new
{
    report.Name,
    release.Version,
    software.Id,
    release. ...
}

但是,SQL查询可能仍然相同。

检查EF生成的SQL(
context.Database.Log
)。我很确定EF足够聪明,可以在这个非常简单的场景中选择最有效的方法。我猜你是说性能方面?你看过EF生成的SQL了吗?您是否尝试过度量这两个不同查询的性能?你最好的办法是用不同的数据集来测量它。只是好奇你所说的“图片完全改变”是什么意思?可能是查询冗长,因为生成的SQL仍然是同一个?啊,是的,我的意思是期望的最终结果影响查询形状选择的方式。
from software in context.Softwares
where software.Id == filterId
     from release in software.Releases
     where release.Version == filterVersion
          from report in release.Reports
select new
{
    report.Name,
    release.Version,
    software.Id,
    release. ...
}