【问题标题】:Many to Many relationship with Fluent NHibernate与 Fluent NHibernate 的多对多关系
【发布时间】:2009-11-18 20:50:12
【问题描述】:

我收到以下错误:“无法弄清楚多对多的另一面应该是什么。” 团队实体:

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

【问题讨论】:

    标签: fluent-nhibernate many-to-many


    【解决方案1】:

    您能否提供导致您的错误的代码?我刚刚尝试了您的映射,它们似乎工作正常(在 fluent 1.0 RTM 和 NH 2.1.1 GA 上使用 SQLite 数据库),对您的 EmployeeMap 进行了少量修改(我假设员工-团队关系是双向的,并且按照documentation您需要将一侧标记为反向)。

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

    当然,如果员工-团队关系不是双向的,我原以为您应该能够为每个人指定不同的 .Table(name) - 但我没有对此进行测试,您似乎得到了不同的结果无论如何(因此为什么最好提供示例代码)

    我还要补充一点,我怀疑 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()));
      }
     }
    

    【讨论】:

    • 我已经解决了问题... .AddFromAssemblyOf() .AddFromAssemblyOf() .AddFromAssemblyOf() .AddFromAssemblyOf()) 是错误的。我只需要使用其中一种方法;)而且我必须将我的属性设为虚拟。
    【解决方案2】:

    Fluent NHibernate 试图通过查看实体名称和集合属性来确定多对多关系的另一端是什么。我相信它不适用于您的情况,因为您的收藏属性不是复数;尝试分别重命名您的收藏集 EmployeesTeams

    另一种方法是在两边手动设置多对多表名,因为这会禁用预测。

    【讨论】:

    • 您的第一个提示不起作用。还是同样的错误。在两边设置多对多表名是什么意思?我该怎么做?
    • 啊好的,有一个表格方法。但它不起作用。我在两个类上都添加了 .Table("EmployeeTeam"),但出现了相同的错误。
    猜你喜欢
    • 2011-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-15
    • 1970-01-01
    相关资源
    最近更新 更多