1

我有这样的设计:

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,但我不喜欢这样,因为我将从我的存储库中调用该方法。

有任何想法吗?

4

3 回答 3

1

您正在混合从数据库中获取数据与控制逻辑。我建议将数据提取到简单的值对象中。然后将其转换为您的公司和员工逻辑负载类。这样,您就可以根据该数据将数据实体与功能分开。

于 2013-10-11T05:24:14.730 回答
0

在 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的更新帖子

于 2013-10-16T15:14:53.807 回答
0

我猜您在映射中使用“属性”作为集合访问器,如果是这样,您描述的行为是您的代码尝试修改集合时的预期行为。

如果您想在域模型中使用该模式,您应该将集合访问器更改为“字段”(使用适当的命名策略),以便告诉 NHibernate 设置支持字段“_employees”而不是属性“员工”。

这将不再触发您尝试访问该集合的代码。

于 2013-10-16T19:19:30.487 回答