Fluent Nhibernate 将多个类映射到单个外键

发布于 2024-10-01 19:50:04 字数 2380 浏览 1 评论 0 原文

我有一个数据库结构,其中一个表扩展另一个表,然后第三个表具有在前两个表中有效的外键。

例如:

TABLE Person
PersonId int
Name varchar
ShirtId int

TABLE Shirt
ShirtId int
Color string

TABLE SpecialShirt
ShirtId int
Sleeves int

类如下所示:

public class Person
{
    public virtual int PersonId { get; set; }
    public virtual string Name { get; set; }
    public virtual Shirt Shirt { get; set; }
    public virtual SpecialShirt SpecialShirt { get; set; }
}

public class Shirt
{
    public Shirt()
    {
        PersonList = new List<Person>();
    }

    public virtual int ShirtId { get; set; }
    public virtual string Color { get; set; }
    public virtual IList<Person> PersonList { get; set; }
    public virtual void AddPerson(Person p)
    {
        PersonList.Add(p);
    }
}

public class SpecialShirt : Shirt
{
    public virtual int Sleeves { get; set; }
}

映射如下所示:

public class TestPersonMap : ClassMap<TestPerson>
{
    public TestPersonMap()
    {
        Table("TestPerson");
        Id(x => x.PersonId).GeneratedBy.Native();
        Map(x => x.Name);
        References(x => x.Shirt).Column("ShirtId");
        References(x => x.SpecialShirt).Column("ShirtId"); // commenting out this line works
    }
}

public class TestShirtMap : ClassMap<TestShirt>
{
    public TestShirtMap()
    {
        Table("TestShirt");
        Id(x => x.ShirtId).GeneratedBy.Native();
        Map(x => x.Color);
        HasMany(x => x.PersonList).KeyColumn("ShirtId").Inverse().Cascade.All();
    }
}

public class TestSpecialShirtMap : SubclassMap<TestSpecialShirt>
{
    public TestSpecialShirtMap()
    {
        Table("TestSpecialShirt");
        KeyColumn("ShirtId");
        Map(x => x.Sleeves).Column("Sleeves");
    }
}

然后,我尝试保存 Person 和 Shirt 的新实例,如下所示:

var shirt1 = new TestShirt() {Color = "Red"};
var person1 = new TestPerson() {Name = "Fred Person", Shirt = shirt1};
shirt1.AddPerson(person1);

session.Save(shirt1);
session.Save(person1);

此代码出现以下错误:

System.ArgumentOutOfRangeException : Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index

如果我删除从 Person 到 SpecialShirt 的引用,它会起作用。我可以在同一列(“ShirtId”)上有两个引用吗?或者有更好的方法吗?我无法真正更改表结构。

I have a database structure where one table extends another table, and then a third table has a foreign key that is valid in the first two tables.

For example:

TABLE Person
PersonId int
Name varchar
ShirtId int

TABLE Shirt
ShirtId int
Color string

TABLE SpecialShirt
ShirtId int
Sleeves int

The classes look like this:

public class Person
{
    public virtual int PersonId { get; set; }
    public virtual string Name { get; set; }
    public virtual Shirt Shirt { get; set; }
    public virtual SpecialShirt SpecialShirt { get; set; }
}

public class Shirt
{
    public Shirt()
    {
        PersonList = new List<Person>();
    }

    public virtual int ShirtId { get; set; }
    public virtual string Color { get; set; }
    public virtual IList<Person> PersonList { get; set; }
    public virtual void AddPerson(Person p)
    {
        PersonList.Add(p);
    }
}

public class SpecialShirt : Shirt
{
    public virtual int Sleeves { get; set; }
}

And the mappings look like this:

public class TestPersonMap : ClassMap<TestPerson>
{
    public TestPersonMap()
    {
        Table("TestPerson");
        Id(x => x.PersonId).GeneratedBy.Native();
        Map(x => x.Name);
        References(x => x.Shirt).Column("ShirtId");
        References(x => x.SpecialShirt).Column("ShirtId"); // commenting out this line works
    }
}

public class TestShirtMap : ClassMap<TestShirt>
{
    public TestShirtMap()
    {
        Table("TestShirt");
        Id(x => x.ShirtId).GeneratedBy.Native();
        Map(x => x.Color);
        HasMany(x => x.PersonList).KeyColumn("ShirtId").Inverse().Cascade.All();
    }
}

public class TestSpecialShirtMap : SubclassMap<TestSpecialShirt>
{
    public TestSpecialShirtMap()
    {
        Table("TestSpecialShirt");
        KeyColumn("ShirtId");
        Map(x => x.Sleeves).Column("Sleeves");
    }
}

I then try saving a new instance of Person and Shirt like this:

var shirt1 = new TestShirt() {Color = "Red"};
var person1 = new TestPerson() {Name = "Fred Person", Shirt = shirt1};
shirt1.AddPerson(person1);

session.Save(shirt1);
session.Save(person1);

This code gets the following error:

System.ArgumentOutOfRangeException : Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index

It works if I remove the reference from Person to SpecialShirt. Howe can I have two references on the same column ("ShirtId")? Or is there a better way? I can't really change the table structure.

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

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

发布评论

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

评论(2

黯然#的苍凉 2024-10-08 19:50:04

这种关系如何运作?
通常,Person 穿着 Shirt,而 Shirt 可以是 ShirtSpecialShirt< /代码>。因为 SpecialShirtShirt,所以 Person 只需要拥有对 Shirt 的引用。 NHibernate 了解所有关于每个具体类的表映射(这就是您所拥有的)。

How does the relationship work?
Usually, a Person wears a Shirt, and a Shirt is either a Shirt or a SpecialShirt. Because a SpecialShirt is a Shirt, a Person need only have a reference to a Shirt. NHibernate knows all about table-per-concrete-class mappings (which is what you have).

蒗幽 2024-10-08 19:50:04

我找到了解决方案。它很丑陋,但它有效。我将命令 DynamicInsert() 添加到 PersonMap 中。所以现在的地图是:

public class TestPersonMap : ClassMap<TestPerson>
{
 public TestPersonMap()
 {
  Table("TestPerson");
  Id(x => x.PersonId).GeneratedBy.Native();
  Map(x => x.Name);
  References(x => x.Shirt).Column("ShirtId");
  References(x => x.SpecialShirt).Column("ShirtId"); 

  DynamicInsert();
 }
}

然后我必须分别保存衬衫和人,因此级联实际上不起作用。

到目前为止,这是有效的。老实说,我不知道 DynamicInsert 是做什么的。在研究这种方法时,我只能找到过时的文档和无用的论坛帖子。

我只能假设这在未来的某个时候会失败。

I found a solution. It's ugly, but it's working. I added the command DynamicInsert() into the PersonMap. So the map is now:

public class TestPersonMap : ClassMap<TestPerson>
{
 public TestPersonMap()
 {
  Table("TestPerson");
  Id(x => x.PersonId).GeneratedBy.Native();
  Map(x => x.Name);
  References(x => x.Shirt).Column("ShirtId");
  References(x => x.SpecialShirt).Column("ShirtId"); 

  DynamicInsert();
 }
}

I then have to save the Shirt and Person separately, so the cascade is not really working.

This is working so far. I honestly don't know what DynamicInsert does. I can only find out-of-date documentation and unhelpful forum threads when researching this method.

I can only assume this will be fail at some point in the future.

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