加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 无法将HBM映射到多对多的FluentNHibernate映射

发布时间:2020-12-15 17:19:23 所属栏目:百科 来源:网络整理
导读:TL; DR:我正在尝试在多对多表上添加一个多对多的Order列来映射多对多. HBM效果很好.无法使FluentNHibernate映射工作. 我有以下两个类,我试图用多对多关系映射: public class User{ public virtual int Id { get; set; } public virtual string Name { get;
TL; DR:我正在尝试在多对多表上添加一个多对多的Order列来映射多对多. HBM效果很好.无法使FluentNHibernate映射工作.

我有以下两个类,我试图用多对多关系映射:

public class User
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    private IDictionary<int,Profile> profilesMap;

    public virtual IEnumerable<Profile> Profiles { get { return this.profilesMap.Select(kvp => kvp.Value); } }

    public User()
    {
        this.profilesMap = new SortedDictionary<int,Profile>();
    }

    public virtual void Add(Profile x)
    {
        profilesMap.Add(x);
    }
}

public class Profile
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
}

profilesMap的关键是配置文件顺序.因此,HBM映射如下:

<class name="User" table="User">
  <id name="Id" column="Id" type="integer">
    <generator class="native" />
  </id>
  <property name="Name" type="string" column="Name" />
  <map name="profilesMap" access="field.camelcase" table="User_Profile">
    <key column="User_Id" />
    <index column="`Order`" type="integer" />
    <many-to-many class="Profile" column="Profile_Id" />
  </map>
</class>
<class name="Profile" table="Profile">
  <id name="Id" column="Id" type="integer">
    <generator class="native" />
  </id>
  <property name="Name" type="string" column="Name" />
</class>

这完美地工作并创建正确的多对多表:

create table User_Profile (
   User_Id INT not null,Profile_Id INT not null,"Order" INT not null,primary key (User_Id,"Order"),constraint FK6BDEDC07D1EDE651 foreign key (Profile_Id) references Profile,constraint FK6BDEDC07650CB01 foreign key (User_Id) references User
)

但是,我并不特别喜欢使用HBM,因为它不是真正的重构.因此,我正在尝试将其转换为FluentNHibernate.这是我尝试用户的多对多映射:

public class UserMap : ClassMap<User>
{
    public UserMap()
    {
        this.Id();
        this.Map(o => o.Name);

        var mapMember = Reveal.Member<User,IEnumerable<KeyValuePair<int,Profile>>>("profilesMap");

        this.HasManyToMany<KeyValuePair<int,Profile>>(mapMember)
            .Access.CamelCaseField()
            .AsMap<int>("`Order`")
            .Table("User_Profile");
    }
}

我希望这可以工作,但是在尝试构建会话工厂时它会爆炸:

An association from the table User_Profile refers to an unmapped class: System.Collections.Generic.KeyValuePair`2[[System.Int32,mscorlib,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089],[ConsoleApplication9.Profile,ConsoleApplication9,Version=1.0.0.0,PublicKeyToken=null]]

我做了很多关于如何让AsMap工作的研究,所以我把它改成了以下内容:

this.HasManyToMany<KeyValuePair<int,Profile>>(mapMember)
    .Access.CamelCaseField().AsMap<int>("`Order`")
    .Element("Profile_id",ep => ep.Type<int>()) // Added.
    .Table("User_Profile");

但是,这会通过不包括Profile_id中的外键(或非空约束)而产生不正确的表:

create table User_Profile (
   User_id INT not null,Profile_id INT,primary key (User_id,constraint FK6BDEDC07650CB01 foreign key (User_id) references "User")

此外,在尝试向用户添加配置文件时,它也会爆炸:

var a = new User() { Name = "A" };
var b = new Profile() { Name = "B" };
a.Add(b);

session.Save(b);
session.Save(a);
session.Flush(); // Error: Unable to cast object of type 'ConsoleApplication9.Profile' to type 'System.IConvertible'.

所以 – 我已经把头发拉了几个小时试图确定如何正确地映射这种与FNH的关系,但我似乎无法得到它.简单的多对多关系看起来很简单,但在尝试添加索引列时,它似乎不起作用.如果有人愿意帮我解决这个问题,我将不胜感激.

解决方法

你有没有看到类似问题的答案?

How to map IDictionary<string,Entity> in Fluent NHibernate

我看到的一个问题是你的manytomany中使用了Element.这可能就是为什么你没有得到profile_id的任何外键设置.另外,如果可能的话,我会尝试为profilesMap添加一个公共访问器.

为了符合您的情况,我将您的映射如下:

HasManyToMany<Profile>(ProfilesMap) //Assuming the addition of a public get accessor
  .Access.CamelCaseField()
  .ParentKeyColumn("User_Id")
  .ChildKeyColumn("Profile_Id")
  .Table("User_Profile")
  .AsMap<int>("Id");

如果您无法添加访问者,可以试试这个

HasManyToMany<Profile>(Reveal.Member<User,object>("profilesMap"))
  .Table("User_Profile")
  .ParentKeyColumn("User_id")
  .ChildKeyColumn("Profile_id")
  .AsMap<int>("`Order`");

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读