Как отобразить и проверить «многие ко многим отношениям» в nhibernate с использованием Fluent nhibernate

StackOverflow https://stackoverflow.com/questions/1795984

Вопрос

Когда я проверяю многочисленных во многих классах, возникает ошибка:

System.ApplicationException: Фактическое количество не равно ожидаемому количеству.

Сущности:

    public interface IEntity
    {
        int Id { get; set; }
    }

    public abstract class Entity : IEntity
    {
        public virtual int Id { get; set; }

        public virtual bool IsPersistent
        {
            get { return isPersistentObject(); }
        }

        public override bool Equals(object obj)
        {
            if (isPersistentObject())
            {
                var persistentObject = obj as Entity;
                return (persistentObject != null) && (Id == persistentObject.Id);
            }

            return base.Equals(obj);
        }

        public override int GetHashCode()
        {
            return isPersistentObject() ? Id.GetHashCode() : base.GetHashCode();
        }

        private bool isPersistentObject()
        {
            return (Id != 0);
        }
    }

    public class Team : Entity
    {
        public virtual string Name { get; set; }
        public virtual ISet<Employee> Employees { get; set; }

        public Team()
        {
            Employees = new HashedSet<Employee>();
        }
    }

    public class Employee : Entity
    {
        public virtual string LastName { get; set; }
        public virtual string FirstName { get; set; }
        public virtual ISet<Team> Teams { get; set; }
        public virtual string EMail { get; set; }

        public Employee()
        {
            Teams = new HashedSet<Team>();
        }
    }

Отображения:

public class TeamMap : ClassMap<Team>
{
    public TeamMap()
    {
        // identity mapping
        Id(p => p.Id).Column("TeamID");

        // column mapping
        Map(p => p.Name);

        // relationship mapping
        HasManyToMany(m => m.Employees)
            .Table("EmployeeTeam")
            .LazyLoad()
            .Cascade.SaveUpdate()
            .AsSet()
            .ParentKeyColumn("TeamID")
            .ChildKeyColumn("EmployeeID");
    }
}

public class EmployeeMap : ClassMap<Employee>
{
    public EmployeeMap()
    {
        // identifier mapping
        Id(p => p.Id).Column("EmployeeID");

        // column mapping
        Map(p => p.EMail);
        Map(p => p.LastName);
        Map(p => p.FirstName);

        // relationship mapping
        HasManyToMany(m => m.Teams).Table("EmployeeTeam")
            .Inverse()
            .Cascade.SaveUpdate()
            .AsSet()
            .LazyLoad()
            .ParentKeyColumn("EmployeeID")
            .ChildKeyColumn("TeamID");
    }
}

Тест:

[TestMethod]
public  void  CanCorrectlyMapEmployee()
{
    var team = new List<Team> {new Team() {Name = "Team1"}};

    new PersistenceSpecification<Employee>(_session)
        .CheckProperty(p => p.EMail, "Mail")
        .CheckProperty(p => p.FirstName, "Firstname")
        .CheckProperty(p => p.Id, 1)
        .CheckProperty(p => p.LastName, "Lastname")
        .CheckList(p => p.Teams,team )
        .VerifyTheMappings();
}

Добавляю ли я сотрудника или команду, моя таблица Roteeeteam всегда пуста.

Я проверил его против SQLLITE с FNH и вручную против SQL Server 2008.

Есть ли у кого -нибудь из вас идея исправить это?

редактировать:

Я был поражен, узнав, что когда я создаю сотрудника и добавляю 2 команды в сотрудника и загружаю созданного сотрудника, у него есть 2 команды. Так что это работает нормально. Но когда я смотрю в свой таблица отношений REPOMETEAM, все пусто. Кто -нибудь может объяснить мне почему?

И кто -нибудь знает, как я могу использовать Fluent Nhibernate, чтобы проверить мои многие на многие отношения?

Заранее спасибо!

Это было полезно?

Решение

Карта сотрудников имеет обратный атрибут. Как вы, наверное, знаете, это означает, что когда вы сохраняете сотрудников, таблица отношений (REPEETEAM) не будет обновлена. Чтобы добавить/удалить новую информацию о отношениях, вы должны добавить сотрудника в команду и сохранить команду.

Итак, в вашем случае - не тестируйте многих для многих на стороне сотрудника, проверьте его на стороне команды. (Если вы хотите, чтобы Nhibernate добавил записи, когда вы добавляете команду в сотрудника, вам придется инвертировать «обратные» атрибуты - отдать их команде, а не сотрудникам, но тогда - та же история с командой).

Почему вы смогли загрузить сотрудника в команды? Из-за кеша на уровне сеанса. Вы, вероятно, сохранили и загрузили сотрудника в той же самой Isession - это означает, что Nhibernate вернул вам точно ссылку на тот же объект, не загружая его из БД. Попробуйте сохранение и загрузку в двух разных сессиях, и вы не увидите команды в работнике.

Примечание: считается хорошей практикой для создания методов, которые будут обеспечивать согласованность между отношениями от многих ко многим, то есть, когда вы добавляете команду в сотрудника, сотрудник добавляется в команду, STH. как это:

class Employee 
{
  // ...
  public void AddTeam(Team team)
  {
     // check for null, etc. 

     Teams.Add(team);
     team.Employees.Add(this);
  }
}

и очень момиллярный метод в классе команды.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top