【问题标题】:Check if lazy loading is enabled检查是否启用了延迟加载
【发布时间】:2019-05-25 18:59:55
【问题描述】:

我有以下型号:

public partial class User
{
    // other properties

    /// <summary>
    /// Gets or sets user roles
    /// </summary>
    public virtual IList<UserRole> UserRoles
    {
        get => _userRoles ?? (_userRoles = UserUserRoleMappings.Select(mapping => mapping.UserRole).ToList());
    }

    /// <summary>
    /// Gets or sets user-user role mappings
    /// </summary>
    public virtual ICollection<UserUserRoleMapping> UserUserRoleMappings
    {
        get => _userUserRoleMappings ?? (_userUserRoleMappings = new List<UserUserRoleMapping>());
        protected set => _userUserRoleMappings = value;
    }
}

在另一个图书馆的服务方法:

    public virtual User GetUserByUsername(string username)
    {
        if (string.IsNullOrWhiteSpace(username))
            return null;

        var user = _dbContext.Users
            .Where(u => u.Username == username)
            .FirstOrDefault();

        return user;
    }

只有启用延迟加载才能正常工作:

        services.AddDbContext<DataContext>(options => options
            .UseLazyLoadingProxies()
            .UseSqlServer(connString));

如果未启用延迟加载,则未填充用户属性。 如果有人尝试在未启用延迟加载的情况下使用我的服务,我想抛出一个异常。怎么做?我试图检查属性_dbContext.ChangeTracker.LazyLoadingEnabled,但是这个属性总是正确的,即使我没有启用延迟加载...

【问题讨论】:

    标签: c# entity-framework-core lazy-loading entity-framework-core-2.1


    【解决方案1】:

    我找到了解决方案(感谢 Tore Aurstad 的提示)。 我在我的 DbContext 中覆盖 OnConfiguring 方法:

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseLazyLoadingProxies(true);
            base.OnConfiguring(optionsBuilder);
        }
    

    那么我们就不需要在启动类中使用UseLazyLoadingProxies()方法来开启延迟加载了

    【讨论】:

    • 很高兴您发现了如何使延迟加载的行为更具确定性。您可以考虑添加“sealed”关键字来阻止您的代码的用户更改任何内容,而是添加另一个虚拟来让他们自定义。另请注意,.net 核心服务可能会注入 DbContextOptions 并更改内容,因此一种更改是将 OnConfiguring 方法拆分为确定的密封部分,然后是客户端可以自定义内容的虚拟方法,但随后他们可能会再次更改延迟加载。
    【解决方案2】:

    您可能误解了延迟加载的用法,提到其他用户可以在未启用延迟加载的情况下使用您的服务。客户端不会打开或关闭延迟加载,由您来实现后端以确保您检查 EF 的空导航属性是否存在。

    延迟加载是 EF Core 2.1 中的一项通用功能,它允许您仅在导航属性被访问时加载它们。这些属性必须是虚拟的,并且类不能被密封。

    也许您在调用客户端服务时误解了“代理”一词。无论如何,是你实现了后端,必须看穿你的数据模型并没有不一致。客户端无法打开或关闭延迟加载。

    如果您不是在谈论您的同事,他们会从另一层(例如数据层)调用 EF 代码。然后你必须看穿空检查是否正确完成。延迟加载通常是件好事,但您可以进行即时加载,例如 .Include,以防您想加载导航属性。

    【讨论】:

    • 目前服务层只有在UseLazyLoadingProxies()启用延迟加载时才能正常工作。如果其他人在没有它的情况下尝试使用此服务层,我想向他抛出一个异常,例如“请启用延迟加载”。有可能吗?
    • 也许您可以在您的数据库上下文中覆盖 OnConfiguring 并检查是否通过 IsConfigured 方法启用了使用延迟加载的属性,然后抛出异常。由你来实现数据层,而不是客户端。但请注意,实现服务层的开发人员可能会覆盖。在这种情况下,考虑密封 DbContext 类并将 OnConfiguring 方法标记为密封。
    • 我尝试查看属性var c = optionsBuilder.IsConfigured;,但它总是正确的,不取决于.UseLazyLoadingProxies()
    猜你喜欢
    • 1970-01-01
    • 2016-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-07
    • 1970-01-01
    • 2019-06-27
    相关资源
    最近更新 更多