c# - 使用 EF LazyLoading 初始化属性?

标签 c# entity-framework lazy-loading lazy-evaluation

更新:我知道我不应该使用 DbSet,所以我按照 Erenga 的建议将实现更改为 ICollection

请考虑以下类:

[Table("Tenant")]
public class Tenant : IEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
    [Key]
    public string Guid { get; set; }
    public virtual ICollection<User> Users { get; set; }
}

[Table("User")]
public class User : IEntity
{
    public int Id { get; set; }

    public string Name { get; set; }
    public string EmailAddress { get; set; }
    public string Password { get; set; }
}

第一个测试创建一个新租户和一个新用户,并将它们存储在适当的表中。

    [Test]
    public void CreateNewUserForNewTenant()
    {
        var user = _applicationContext.Users.Create();
        user.Name = "barney";
        user.EmailAddress = "barney@flinstone.com";

        var tenant = _applicationContext.Tenants.Create();
        tenant.Name = "localhost";
        tenant.Guid = Guid.NewGuid().ToString();

        tenant.Users.Add(user); // NullReferenceException, I expected the EF would LazyLoad the reference to Users?!
        _tenantRepository.Add(tenant);
        _applicationContext.SaveChanges();
    }

此测试将在 NullReferenceException 上失败,因为属性 Users 未初始化。

我应该如何更改我可以依赖 EF 提供的 LazyLoading 的代码?

最佳答案

我在这里看到了 2 个问题。

  1. 如@SimonWhitehead 所述,引用类型默认初始化为 null。延迟加载仅适用于 EF 创建的实体。这些实际上是您的类的子类,包含延迟加载的附加逻辑。

  2. DbSet 不是实体支持的集合类型。您需要将类型更改为 ICollectionISetIList

这是一个工作示例

[Table("Tenant")]
public class Tenant : IEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
    [Key]
    public string Guid { get; set; }
    public virtual ICollection<User> Users { get; set; }
}

[Table("User")]
public class User : IEntity
{
    public int Id { get; set; }

    public string Name { get; set; }
    public string EmailAddress { get; set; }
    public string Password { get; set; }
}

[Test]
public void CreateNewUserForNewTenant()
{
    var user = _applicationContext.Users.Create();
    user.Name = "barney"; 
    user.EmailAddress = "barney@flinstone.com";

    var tenant = _applicationContext.Tenents.Create();
    tenant.Name = "localhost";
    tenant.Guid = Guid.NewGuid().ToString();

    tenant.Users = new List<User> { user };
    _tenantRepository.Add(tenant);
    _applicationContext.SaveChanges();
}

关于c# - 使用 EF LazyLoading 初始化属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14547728/

相关文章:

c# - OData(Wcf数据服务)到Swagger Generation

HttpWebRequest 方法 "This stream does not support seek operations."的 C# 异常 "PUT"

c# - 带有 EF 的 ASP.NET 成员提供程序

javascript - 如何在 Angular 4 模块中延迟加载库?

Python 3 可迭代惰性 block 获取

c# - 没有 NET 3.0 的 WCF

c# - RefCount 在 AtlUnadvise 调用后保持不变

entity-framework - 如何从解决方案资源管理器中选择特定的实体图

c# - 我可以避免 Entity Framework 使用 SQL_VARIANT 来查询吗?

ruby-on-rails - 如何在 Rails 2.3.3 中有条件地分配 ActionController::Base.session