更新:我知道我不应该使用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的代码?
答案 0 :(得分:2)
var tenant = new Tenant
{
Name = "localhost",
Guid = Guid.NewGuid().ToString(),
Users = new List<User> { user }
};
答案 1 :(得分:2)
我在这里看到了两个问题。
正如@SimonWhitehead所提到的,默认情况下,引用类型初始化为null。延迟加载仅适用于EF创建的实体。这些实际上是您的类的子类,包含延迟加载的附加逻辑。
DbSet
不是实体支持的集合类型。您需要将类型更改为ICollection
,ISet
或IList
。
这是一个有效的例子
[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();
}
答案 2 :(得分:0)
我认为你期待这样的事情(不是线程安全):
[Table("Tenant")]
public class Tenant : IEntity
{
private DbSet<User> _users;
public int Id { get; set; }
public string Name { get; set; }
[Key]
public string Guid { get; set; }
public virtual ICollection<User> Users
{
get
{
if (_users == null)
_users = new List<Users>();
return _users;
}
set { _users = value; }
}
}
我确信Lazy<T>
课程也可以以某种方式使用,但我对这门课程并不熟悉。