Отношения многие ко многим с Fluent NHibernate - PullRequest
0 голосов
/ 18 ноября 2009

Я получаю следующую ошибку: «Не могу понять, какой должна быть другая сторона многих ко многим». Субъект команды:

public class Team : IEntity
{
    public int Id { get; set; }

    public string Name { get; set; }

    public IList<Employee> Employee { get; set; }

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

Юридическое лицо сотрудника:

public class Employee : IEntity
{
    public int Id { get; set; }

    public String LastName { get; set; }

    public string FirstName { get; set; }

    public IList<Team> Team { get; set; }

    public string EMail { get; set; }

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

Состав команд:

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

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

        // relationship mapping
        HasManyToMany<Employee>(m => m.Employee);
    }
}

Отображение сотрудников:

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

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

        // relationship mapping
        HasManyToMany<Team>(m => m.Team);
    }
}

Ни у кого нет ответа?

Редактировать: ошибка возникает в следующем коде:

public static ISessionFactory CreateSessionFactory()
{
    return Fluently.Configure()
        .Database(MsSqlConfiguration.MsSql2008
        .ConnectionString(c=>
            c.Database("Ariha")
            .TrustedConnection()
            .Server("localhost")
            ).ShowSql())
        .Mappings(m => m.FluentMappings
            .AddFromAssemblyOf<BookMap>()
            .AddFromAssemblyOf<MagazineMap>()
            .AddFromAssemblyOf<EmployeeMap>()
            .AddFromAssemblyOf<TeamMap>())
        .ExposeConfiguration(BuildSchema)
        .BuildSessionFactory();
}

редактировать: здесь все решение: http://rapidshare.com/files/309653409/S.O.L.I.D.Ariha.rar.html

Ответы [ 2 ]

3 голосов
/ 20 ноября 2009

Не могли бы вы предоставить код, который вызывает вашу ошибку? Я только что попробовал ваши сопоставления, и они, кажется, работают нормально (на беглой версии 1.0 RTM и NH 2.1.1 GA с базой данных SQLite), с незначительной модификацией к вашему EmployeeMap (я предположил, что отношения сотрудник-команда двунаправлены и согласно документация необходимо пометить одну сторону как обратную).

 // relationship mapping
 HasManyToMany<Team>(m => m.Team).Inverse();

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

Я бы также добавил, что я подозреваю, что семантика Set (вместо Bag) будет более подходящей для свойств Employee.Team и Team.Employee. (Несмотря на это, не делайте ничего, что предполагает, что порядок сохранен, нет гарантии, что он будет)

Предлагаемое отображение и пример:

 public class Team
 {
  public int Id { get; set; }
  public string Name { get; set; }
  public ICollection<Employee> Employee { get; set; }
  public Team() { Employee = new List<Employee>(); }
 }

 public class Employee
 {
  public int Id { get; set; }
  public String LastName { get; set; }
  public string FirstName { get; set; }
  public ICollection<Team> Team { get; set; }
  public string EMail { get; set; }
  public Employee() { Team = new List<Team>(); }
 }

 public class TeamMap : ClassMap<Team>
 {
  public TeamMap()
  {
   Not.LazyLoad();
   // identity mapping
   Id(p => p.Id);
   // column mapping
   Map(p => p.Name);
   // relationship mapping
   HasManyToMany<Employee>(m => m.Employee).AsSet();
  }
 }

 public class EmployeeMap : ClassMap<Employee>
 {
  public EmployeeMap()
  {
   Not.LazyLoad();
   // identifier mapping
   Id(p => p.Id);
   // column mapping
   Map(p => p.EMail);
   Map(p => p.LastName);
   Map(p => p.FirstName);
   // relationship mapping
   HasManyToMany<Team>(m => m.Team).Inverse().AsSet();
  }
 }

 [TestFixture]
 public class Mapping
 {
  [Test]
  public void PersistDepersist()
  {
   var fcfg = Fluently.Configure()
    .Database(SQLiteConfiguration.Standard.UsingFile("testdb.sqldb"))
    .Mappings(mc =>
    {
     mc.FluentMappings.Add(typeof (TeamMap));
     mc.FluentMappings.Add(typeof (EmployeeMap));
    })
    .ExposeConfiguration(cfg => new SchemaExport(cfg).Execute(false, true, false));

   var sess = fcfg.BuildSessionFactory().OpenSession();


   var teams = Enumerable.Range(0, 4).Select(i => new Team() {Name = "Team " + i}).ToArray();
   var employees = Enumerable.Range(0, 10).Select(i => new Employee() {FirstName = "Employee " + i}).ToArray();

   teams[0].Employee = new List<Employee>() {employees[0], employees[3], employees[5]};
   teams[1].Employee = new List<Employee>() {employees[7], employees[2], employees[5]};
   teams[3].Employee = new List<Employee>() {employees[0], employees[8], employees[9]};

   foreach (var team in teams)
    foreach (var employee in team.Employee)
     employee.Team.Add(team);

   Console.WriteLine("Dumping Generated Team/Employees:");
   Dump(teams);
   Dump(employees);

   using (var t = sess.BeginTransaction())
   {
    foreach (var team in teams)
     sess.Save(team);
    foreach (var employee in employees)
     sess.Save(employee);
    t.Commit();
   }

   sess.Flush();
   sess.Clear();

   var teamsPersisted = sess.CreateCriteria(typeof (Team)).List<Team>();
   var employeesPersisted = sess.CreateCriteria(typeof (Employee)).List<Employee>();

   Assert.AreNotSame(teams, teamsPersisted);
   Assert.AreNotSame(employees, employeesPersisted);

   Console.WriteLine();
   Console.WriteLine();
   Console.WriteLine("Dumping Depersisted Team/Employees:");
   Dump(teamsPersisted);
   Dump(employeesPersisted);
  }

  private static void Dump(IEnumerable<Team> teams)
  {
   foreach (var team in teams)
    Console.WriteLine("Team: " + team.Name + " has members: " + string.Join(", ", team.Employee.Select(e => e.FirstName).ToArray()));
  }

  private static void Dump(IEnumerable<Employee> employees)
  {
   foreach (var employee in employees)
    Console.WriteLine("Employee: " + employee.FirstName + " in teams: " + string.Join(", ", employee.Team.Select(e => e.Name).ToArray()));
  }
 }
1 голос
/ 19 ноября 2009

Свободно NHibernate пытается определить, что является другой стороной отношения «многие ко многим», просматривая имена сущностей и свойства коллекции. Я считаю, что это не работает в вашем случае, потому что ваши свойства коллекции не множественного числа; попробуйте переименовать свои коллекции Employees и Teams соответственно.

Другой способ - вручную задать имя таблицы «многие ко многим» с обеих сторон, так как это отключит прогноз.

...