与Fluent Nhibernate建立一对多的关系

时间:2013-05-21 20:16:59

标签: c# nhibernate fluent-nhibernate fluent-nhibernate-mapping

我和我的同事有点争吵,我似乎无法找到答案,但这是非常基本的东西。

在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我并没有举例说明我正在尝试实施的内容。 你们可以建议或帮我找一份解释正确方法的文件吗?我对吗? 谢谢。

1 个答案:

答案 0 :(得分:12)

这里提出的建议完全可以在nHibernate框架内完成。显然你已经列出了模型而不是映射文件,但是Fluent nHibernate允许你以这种方式配置你的映射而没有问题。

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

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

基本上我所说的是在决定如何定义映射时没有绝对的“正确方法” - 你真的需要平衡丰富的对象模型和查询性能,但是如果你需要你的具体例子是完全可以接受的它

我刚刚重新阅读了您的问题,我不确定您是否也在询问以这种方式配置的映射示例,因此,如果您确实需要一些示例,请告诉我,我会为您整理一些。< / p>

要实现您描述的关系,您需要以下地图类(我添加了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");
    }
}

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

如果您有任何更具体的问题让我知道,希望这会有所帮助