NHibernate 自动映射问题

发布于 2024-11-05 09:38:28 字数 1563 浏览 1 评论 0原文

最近我在 Fluent NHibernate 的 Automapping 中发现了一个奇怪的行为。我有以下类结构(为了酿造而切断了一些属性)。

public class UserGroup
{
    public virtual UserGroup ParentGroup { get; set; }

    public virtual UserGroupMember Manager { get; protected set; }

    public virtual ISet<UserGroupMember> Members { get; protected set; }
}

UserGroup

public class UserGroupMember : BaseEntity
{
    public virtual User User { get; set; }

    public virtual UserGroup Group { get; set; }
}

的映射:

public class UserGroupMap : IAutoMappingOverride<UserGroup>
{
    public void Override(AutoMapping<UserGroup> mapping)
    {
        mapping.HasMany(el => el.Members)
            .Cascade
            .AllDeleteOrphan().Inverse().LazyLoad();
    }
}

自动映射在 UserGroupMember 表中创建两列(均为外键)以反映 UserGroup 和 UserGroupMembers 之间的关系。我发现生成的映射包含错误的列(如下所示):

<set cascade="all-delete-orphan" inverse="true" lazy="true" name="Members" mutable="true">
    <key>
      <column name="Parent_Id" />
    </key>
    <one-to-many class="Groups.Data.UserGroupMember, Server, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</set>

这会导致错误的查询:

  1. 在 UserGroupMember 中插入时使用 Group_Id(这是正确的),而不使用 Parent_Id
  2. 在 UserGroupMember 中选择时使用

Group_Id - Parent_Id是 UserGroupMember 映射文件中的列,反映 UserGroupMember 中的 Group 属性。

我尝试修改映射添加 .KeyColumn("Group_Id") 它解决了问题。但是有没有办法让 Fluent NHibernate “以正确的方式思考”呢?

Recently I came across a strange behavior in Automapping of Fluent NHibernate. I have the following class structure (some properties cut off for the sake of brewity).

public class UserGroup
{
    public virtual UserGroup ParentGroup { get; set; }

    public virtual UserGroupMember Manager { get; protected set; }

    public virtual ISet<UserGroupMember> Members { get; protected set; }
}

and

public class UserGroupMember : BaseEntity
{
    public virtual User User { get; set; }

    public virtual UserGroup Group { get; set; }
}

The mapping for UserGroup:

public class UserGroupMap : IAutoMappingOverride<UserGroup>
{
    public void Override(AutoMapping<UserGroup> mapping)
    {
        mapping.HasMany(el => el.Members)
            .Cascade
            .AllDeleteOrphan().Inverse().LazyLoad();
    }
}

The automapping creates two column (both of which are foreign keys) in the UserGroupMember table to reflect the relation between UserGroup and UserGroupMembers. I've found out that the generated mapping contains wrong column (as seen below):

<set cascade="all-delete-orphan" inverse="true" lazy="true" name="Members" mutable="true">
    <key>
      <column name="Parent_Id" />
    </key>
    <one-to-many class="Groups.Data.UserGroupMember, Server, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</set>

which results in wrong queries:

  1. While insert in UserGroupMember - Group_Id is used (which is right), not using Parent_Id
  2. While select in UserGroupMember - Parent_Id is used

Group_Id is the column in UserGroupMember mapping file which reflects the Group property in UserGroupMember.

I tried to modify the mapping adding .KeyColumn("Group_Id") and it is solves the problem. But is there any way to make Fluent NHibernate 'think the right way'?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

鹤仙姿 2024-11-12 09:38:28

这是凭记忆写的,因为我还没有准备好测试代码。

使用双向多对多时,有时必须帮助 FHN 计算列名称(如果两侧的列名称不“相似”)。

例如,这应该正确映射,

public class User
{
    public IList<Group> Groups { get; set; }
}

public class Group    
{
    public IList<User> Users { get; set; }
}

虽然这不会

public class User
{
    public IList<Group> BelongsTo { get; set; }
}

public class Group    
{
    public IList<User> Contains { get; set; }
}

根据经验,如果自动映射(有或没有约定)没有生成正确的列名称,特别是对于不平凡的情况,请毫不犹豫地进行覆盖来设置这些列名称手动。

This is from memory, as I don't have test code ready.

When using bidirectional many-to-many, you sometimes have to help FHN figure columns names, if they're not "alike" on both sides.

For example this should map correcly

public class User
{
    public IList<Group> Groups { get; set; }
}

public class Group    
{
    public IList<User> Users { get; set; }
}

While this would not

public class User
{
    public IList<Group> BelongsTo { get; set; }
}

public class Group    
{
    public IList<User> Contains { get; set; }
}

As a rule of thumb, if automapping (with or without conventions) doesn't generate right columns names, especially for non trivial cases, do not hesitate to put an override to set those column names manually.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文