方法FindByQueryAsNoTracking()
的实现如下:
public IEnumerable<T> FindByAsNoTracking(Expression<Func<T, bool» predicate)
{
IQueryable<T> query = Dbset.Where(predicate).AsNoTracking().AsQueryable();
return query;
}
如果我们使用以下实现的FindByAsQuery
:
public IQueryable<T> FindByQuery(Expression<Func<T, bool» predicate)
{
IQueryable<T> query = Dbset.Where(predicate).AsQueryable();
return query;
}
速度会更好?
答案 0 :(得分:2)
AsNoTracking(IQueryable)
返回一个新查询,其中返回的实体将不被缓存在DbContext或 ObjectContext 中。此方法通过调用基础查询对象的AsNoTracking方法来工作。如果基础查询对象没有AsNoTracking
方法,则调用此方法将无效。
5.1禁用更改跟踪以减少状态管理开销 您处于只读方案,并且希望避免以下操作的开销 将对象加载到ObjectStateManager中,可以发出“否 跟踪”查询。可以在查询中禁用更改跟踪 级别。
请注意,尽管通过禁用更改跟踪您可以有效地 关闭对象缓存。当您查询实体时,我们无法 通过拉出先前实现的查询来跳过实现 来自ObjectStateManager的结果。如果您反复查询 对于在相同上下文中的相同实体,您实际上可能会看到 启用更改跟踪可以提高性能。
使用ObjectContext,ObjectQuery和ObjectSet实例进行查询时 一旦设置了MergeOption,它就会记住 由它们组成的将继承父级的有效MergeOption 查询。使用DbContext时,可以通过调用 DbSet上的AsNoTracking()修改器。
简而言之,是的,通过使用AsNoTracking
,您可以获得更好的性能,尤其是当您要加载大量数据行时,但是不要忘记它不会影响SQL生成的查询,只会增加.NET
中的效果。
ps: 图表取自StaticVoid blog。
答案 1 :(得分:1)
您需要使用编译查询(LINQ到实体)
请参阅enter link description here
还有一件事,如果您想要子数据,请设置 LazyLoding = true
默认在EntityFramework DBContext类中为LazyLoding = true
实体框架中的延迟加载
延迟加载会延迟相关数据的加载,直到您明确要求为止。这与渴望加载相反。 例如, Student 实体包含 StudentAddress 实体。在延迟加载中,上下文首先从数据库加载 Student 实体数据,然后在我们访问< strong> StudentAddress 属性,如下所示。
using (var ctx = new SchoolDBEntities())
{
//Loading students only
IList<Student> studList = ctx.Students.ToList<Student>();
Student std = studList[0];
//Loads Student address for particular Student only (seperate SQL query)
StudentAddress add = std.StudentAddress;
}
上面显示的代码将导致两个SQL查询。首先,它将获取所有学生:
SELECT
[Extent1].[StudentID] AS [StudentID],
[Extent1].[StudentName] AS [StudentName],
[Extent1].[StandardId] AS [StandardId]
FROM [dbo].[Student] AS [Extent1]
然后,当我们获得StudentAddress的引用时,它将发送以下查询:
exec sp_executesql N'SELECT
[Extent1].[StudentID] AS [StudentID],
[Extent1].[Address1] AS [Address1],
[Extent1].[Address2] AS [Address2],
[Extent1].[City] AS [City],
[Extent1].[State] AS [State]
FROM [dbo].[StudentAddress] AS [Extent1]
WHERE [Extent1].[StudentID] = @EntityKeyValue1',N'@EntityKeyValue1 int',@EntityKeyValue1=1
禁用延迟加载
我们可以为特定实体或上下文禁用延迟加载。要关闭特定属性的延迟加载,请勿使其变为虚拟。要关闭上下文中所有实体的延迟加载,请将其配置属性设置为false。
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Core.Objects;
using System.Linq;
public partial class SchoolDBEntities : DbContext
{
public SchoolDBEntities(): base("name=SchoolDBEntities")
{
this.Configuration.LazyLoadingEnabled = false;
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
}
延迟加载规则:
context.Configuration.ProxyCreationEnabled应该为true。
context.Configuration.LazyLoadingEnabled应该为true。
导航属性应定义为公共虚拟属性。上下文
如果该属性未定义为virtual,则不会进行延迟加载。