我只是用c#和EF迈出了第一步,并有一个现有的数据库,我将其作为EF数据模型导入到我的Web API项目中。我发现延迟加载是启用的,因此我的一些查询非常慢。因此,我希望通过手动从生成的模型中的导航属性中删除"virtual"关键字来禁用它。
据我所知,每次我在数据库中进行模式更改时,我都需要重新生成整个EF数据模型,这将覆盖我删除虚拟关键字的模型,这意味着我将不得不再次这样做。是否有一种方法可以配置EF默认禁用延迟加载?我发现了几个与此相关的帖子,例如将其放入我的数据库上下文中。
this.Configuration.LazyLoadingEnabled = false;
,但提供的解决方案似乎都不起作用。
在创建.edmx
文件的文件夹中添加与ApplicationDbContext
相同名称的类,并将其标记为部分,如
public partial class ApplicationDbContext: DbContext
在该类中添加一个静态方法,返回您的ApplicationDbContext
对象,如
public static ApplicationDbContext Create()
并在此方法的定义中创建一个ApplicationDbContext
的新对象,并将其LazyLoadingEnabled
设置为false
,如
var applicationDbContext = new ApplicationDbContext();
applicationDbContext.Configuration.LazyLoadingEnabled = false;
,最后返回新创建的对象。所以你的部分类的代码看起来像
public partial class ApplicationDbContext : DbContext
{
public static ApplicationDbContext Create()
{
var applicationDbContext = new ApplicationDbContext();
applicationDbContext.Configuration.LazyLoadingEnabled = false;
return applicationDbContext;
}
}
在访问数据库时使用ApplicationDbContext.Create()
而不是new ApplicationDbContext()
您可以根据自己的喜好修改用于模型生成的T4模板(这些是.tt
文件)。
我发现延迟加载是启用的,因此我的一些查询非常慢。
你确定延迟加载真的是问题所在吗?通常情况下,延迟加载对查询性能没有影响,但如果在执行查询之后,在循环中使用它来加载属性,则会产生负面影响(N+1)
当然,如果你输入Configuration.LazyLoadingEnabled = false;
,它会停用它。
问题可能不在于延迟加载,而在于代理的创建。尝试将ProxyCreationEnabled = false
放在构造函数中并检查它是否更好(它还将禁用延迟加载)。否则,如果您的数据是只读的,您也可以在执行查询时尝试使用AsNoTracking扩展方法。