5

我和我的同事发生了一些争论,我似乎找不到答案,但这是非常基本的东西。

在 Fluent Nhibernate 实体中建立一对多关系。

让我们以角色和用户为例。一个角色可以分配给多个用户,所以我让我的实体胆量看起来像:

public class User
{
    [Required]
    public virtual string FirstName { get; set; }
    public virtual Role Role { get; set; }
}

和角色

public class Role
{
    [Required]
    public virtual string Name { get; set; }
    public virtual IList<User> Users{ get; set; }

    public Role()
    {
        Users = new List<Users>();
    }
}

如您所见,我在角色中引用了一组用户,有点说每个角色将有多个用户。用户实体具有标识用户所属角色所需的角色实体引用。

在我看来,这是正确的链接方式,我的同事说,Role为用户提供参考将创建循环参考。谁是对的?

我试着在网上找到答案。我认为这个问题告诉我我是对的: Fluent NHibernate Many to one mapping

但是后来我在这里查看了一个 Fuent Nhibernate 示例项目 https://github.com/jagregory/fluent-nhibernate/tree/master/src/Examples.FirstAutomappedProject/Entities并且我不是我正在尝试的示例实施。你们能建议或帮助我找到解释正确方法的文件吗?我对吗?谢谢你。

4

1 回答 1

12

您在这里提出的建议在 nHibernate 框架内是完全可能和允许的。显然,您列出了模型而不是映射文件,但 Fluent nHibernate 允许您以这种方式配置映射而不会出现问题。

您是否真的选择以这种方式映射关系完全取决于个人喜好和具体场景。我以这种方式映射模型,但同样选择不这样做,主要是因为在某些情况下,过度复杂化对象图是没有意义的。以在数据库中的多个表中多次引用的查找表(例如 Culture 或 Locale)为例,当映射它时,我将在每个父模型中都有一个 Culture 属性,但不会有父对象的集合在文化模型中 - 它只是没有意义。

您还需要考虑通过持久层加载数据 - 如果您创建这种关系并且只需要一个简单的角色列表,您需要考虑何时或是否填充 users 集合 - 您可以指定预先加载或延迟加载,但根据我的经验,在查询中使用相应的 Fetch 命令指定预加载可以导致对数据库的更优化调用。

基本上我要说的是,在决定如何定义映射时没有绝对的“正确方法”——您确实需要平衡丰富的对象模型与查询性能,但如果您需要,您的具体示例是完全可以接受的。

我刚刚重新阅读了您的问题,我不确定您是否还要求提供以这种方式配置的映射示例,所以如果您确实需要一些示例,请告诉我,我会为您整理一些。

要实现您描述的关系,您需要以下地图类(我添加了 Id 属性,因为我猜您有这些):

对于角色:

public class RoleMap : ClassMap<Role>
{
    public RoleMap()
    {
          Table(@"Roles");
          Id(x => x.Id).GeneratedBy.Assigned();
          Map(x => x.Name).Column("Name");
          HasMany<User>(x => x.Users)
            .Inverse()
            .KeyColumns.Add("RoleId", mapping => mapping.Name("RoleId"));
    }
}

对于用户:

public class UserMap : ClassMap<User>
{
   public UserMap()
    {
          Table(@"Users");
          Id(x => x.Id).GeneratedBy.Assigned();
          Map(x => x.FirstName);
          Map(x => x.RoleId);    
          References(x => x.Role)
            .Class<Role>()
            .Columns("RoleId");
    }
}

我不会太拘泥于“你的方法与他们的方法” - 以上是完全可以接受的,并且取决于您在代码中使用对象模型时的要求。或者,如果您不希望角色映射中的用户集合,只需删除该属性和关联的 HasMany 映射声明。上面要注意的一件事是 .Inverse() 规范已将 Role 和 User 之间关系的管理委托给 Users 实体,这基本上是添加或编辑现有用户并提供 RoleId 的过程。将建立关系。

希望这会有所帮助,如果您有任何更具体的问题,请告诉我

于 2013-05-21T20:48:46.457 回答