避免在使用 NHibernate 时在 setter 属性中存在逻辑
本文关键字:属性 存在 setter 时在 NHibernate | 更新日期: 2023-09-27 18:34:47
我有这样的设计:
public class Employee {
//...
}
public class Company {
private IList<Employee> _employees;
public IList<Employee> Employees {
get { return _employees; }
set {
if (_employees == value) {
return;
}
_employees = value;
//Some logic here. Eg:
//Raise PropertyChanged
//Iterate over the new values to suscribe to some events, etc.
}
}
}
当我尝试执行以下操作时:
var employees = session.Query<Company>().Fetch(x => x.Employees).ToList();
它抛出一个LazyInitializationException
:
非法进入装载收集
我发现的唯一解决方法是将逻辑移动到一个方法,使该方法公开(和虚拟(并为employees
中的每个实例调用该方法,但我不喜欢这样,因为我将从我的存储库调用该方法。
有什么想法吗?
您正在将从数据库获取数据与控制逻辑混合在一起。我建议将数据提取到简单的值对象中。然后将其转换为您的公司和员工逻辑丰富的类。这样,您就可以将数据实体与基于该数据的功能分开。
在 Nhibernate 中,你的集合类不应该暴露在外面的世界。 您的典型域如下所示
public class Company
{
public virtual String Id { get; set; }
public virtual ICollection<Employee> Employees { get; protected set; }
public Company()
{
Employees = new List<Employee>();
}
public void AddEmployee(Employee employee)
{
if (Employees.Contains(employee))
return;
Employees.Add(employee);
employee.Company = this;
}
public void RemoveEmployee(Employee employee)
{
if (!Employees.Contains(employee))
return;
Employees.Remove(employee);
}
}
public class Employee
{
public virtual String Id { get; set; }
public virtual String FullName { get; set; }
public virtual Company Company { get; set; }
}
我同意第一个响应者对用户视图模型和INPC说的那些,但是如果你想直接绑定到你的域对象,你可以直接将INPC注入到你的域对象中。
请参阅Ayende的原始帖子和Ricardo的更新帖子
我猜你在映射中使用"property"作为集合访问器,如果是这样,你描述的行为是代码尝试修改集合时的预期行为。
如果要在域模型中使用该模式,则应将集合访问器更改为"field"(使用适当的命名策略(,以便告诉 NHibernate 设置支持字段"_employees"而不是属性"Employees"。
这不会再触发尝试访问集合的代码。