views:

426

answers:

1

In my domain, an Employee and a Department have a one-to-many bidirectional relationship; to let the child Employee synchronize this, I have an 'internal' access field for the Set (Iesi for NHibernate) of Employees that are in the Department, which would otherwise be readonly public. Like so:

Department class:

protected internal ISet<Employee> _staff;  
public virtual ReadOnlyCollection<Employee> Staff {  
   get { return new List<Employee>(_staff).AsReadOnly(); }   
}  
public virtual void AddStaff(Employee emp) {
    emp.Department = this;  } 
}

Employee class:

private Department _department;
public virtual Department Department {
   set {
       // check valid value, etc.
       value._staff.Add(this);
   }
}

I made access in my (FNH) mapping AsField(Prefix.Underscore), but since I can't make the Department._staff field virtual NH is not happy. I guess I could make the field a virtual property and force feed it, but that feels like I'm making the domain class overly aware of persistence.

I'm learning both NH and FNH and I know I need a good primer in relationship mapping, but my primary question for this post is the logic in my domain classes:
1) Is this a good c# programming pattern for a readonly set in a biderectional relationship?
2) What is the best way to make this more usable to NHibernate?

Thanks for sharing!
Berryl

+6  A: 

I implement one-to-many relationships using this pattern:

public class Department
{
    private IList<Employee> _staff = new List<Staff>();

    public virtual IEnumerable<Employee> Staff
    {
        get { return _staff; }
    }

    // Add and Remove have additional checks in them as needed

    public virtual void AddStaff(Employee staff)
    {
        staff.Department = this;
        _staff.Add(staff);
    }

    public virtual void RemoveStaff(Employee staff)
    {
        staff.Department = null;
        _staff.Remove(staff);
    }
}

 

public class Employee
{
    public virtual Department Department { get; internal set; }
}

In this case, Department is the inverse side of the relationship.

Jamie Ide
Hi JamieSorry for the late credit due, as this works well. Do you think it would be possible to flip the logic and let the _staff ISet be internally visible? How would the mapping look if so?Thanks again for the good response.
Berryl