许多人来自"两个"关系增加额外的FK(也没有工作)

时间:2014-03-25 13:38:06

标签: c# nhibernate fluent-nhibernate

我有以下课程

public class Foo
{
    public virtual int Id { get; protected set; }
    public virtual IEnumerable<Bar> Bars { get; protected set; }
}

public class Bar
{
    public virtual int Id { get; protected set; }
    public virtual Foo Foo1 { get; set; }
    public virtual Foo Foo2 { get; set; }
}

以下(可能是不正确的)映射

public class FooMap : ClassMap<Foo>
{
    public FooMap()
    {
        this.Id(x => x.Id);
        this.HasMany(x => x.Bars);
    }
}

public class BarMap : ClassMap<Bar>
{
    public BarMap()
    {
        this.Id(x => x.Id);
        this.References(x => x.Foo1);
        this.References(x => x.Foo2);
    }
}

创建表格时,FNH正在执行以下操作:

create table "Bar" (
    Id  integer primary key autoincrement,
   Foo1_id INT,
   Foo2_id INT,
   Foo_id INT,
   constraint FK52E419EE7F0CDD3 foreign key (Foo1_id) references "Foo",
   constraint FK52E419EE3C0DCDD3 foreign key (Foo2_id) references "Foo",
   constraint FK52E419EE34BDF7FF foreign key (Foo_id) references "Foo"
)

即。有一个额外的FK参考。

这意味着调用someBar.Foo1很好,但调用soFoo.Bars始终为空。

我已经研究过使用

this.HasMany(x => x.Bars).KeyColumns.Add("Foo1_id", "Foo2_id");

但这会返回错误:

  

外键(FK52E419EE660E4A59:Bar [Foo1_id,Foo2_id]))必须与引用的主键具有相同的列数(Foo [Id])。

映射这种关系形式的正确方法是什么?


如果我们有

,澄清预期结果
Table:Foos   |  Table:Bars
Id           |  Id    Foo1_id   Foo2_id
--           |  -----------------------
11           |  1     11        12
12           |  2     12        11
13           |  3     12        13

然后this.Session.Get<Foo>(11).Bars应该包含Bar Id1的{​​{1}}。

1 个答案:

答案 0 :(得分:1)

我非常确定你不能做你所要求的,使用auto - &#34; merge voodoo&#34; Foo.Bars(因此我在问题的评论中的问题)。

我认为这就是你能做的。请注意,我提出了一些比Foo和Bar更不通用的东西。

我有一个&#34;项目&#34;。还有一个员工。每个员工都可以拥有&#34;或者&#34;工作&#34;一个项目(或两者兼而有之)。显然,在现实世界中,迫使员工只拥有或在单个项目上工作是愚蠢的。 但它可以在这里工作。

该项目有(许多)业主和工人。我有一个获得(readonly get)属性的任何人与项目相关联。这是你合并两个不同关系的地方。

我对这个懒惰初始化一无所知。我只是指出你正在寻找的自动合并事件......可能不在卡片中。

public class Project
{
    public virtual int ProjectKey { get; set; }
    public virtual string ProjectName { get; set; }
    public virtual IList<Employee> ProjectOwners { get; set; }
    public virtual IList<Employee> ProjectWorkers { get; set; }

    public virtual IList<Employee> AnybodyAssociatedWithThisProject 
    {
        get
        {
            List<Employee> returnItems = new List<Employee>();
            if (null != this.ProjectOwners)
            {
                returnItems.AddRange(this.ProjectOwners);
            }
            if (null != this.ProjectOwners)
            {
                returnItems.AddRange(this.ProjectWorkers);
            }
            return returnItems;
        }
    }
}


public class Employee
{
    public virtual int EmployeeKey { get; set; }
    public virtual string SSN { get; set; }
    public virtual Project OwnedProject { get; set; }
    public virtual Project WorkedOnProject { get; set; }
}


public class ProjectMap : ClassMap<Project>
{
    public ProjectMap()
    {
        Id(x => x.ProjectKey);
        Map(x => x.ProjectName);
        HasMany(x => x.ProjectOwners)
            .KeyColumn("OwnedProjectKey");
        HasMany(x => x.ProjectWorkers)
            .KeyColumn("WorkedOnProjectKey");
        Table("Project");
    }
}

public class EmployeeMap : ClassMap<Employee>
{
    public EmployeeMap()
    {
        Id(x => x.EmployeeKey);
        Map(x => x.SSN);
        References(x => x.OwnedProject).Column("OwnedProjectKey");
        References(x => x.WorkedOnProject).Column("WorkedOnProjectKey");
        Table("Employee");
    }
}

我测试了一些数据。 一切似乎都有效。一个警告是,如果员工拥有&#34;和&#34;工作&#34;一个项目,我的简单&#34; .AddRange&#34;合并代码将复制该Employee。 除此之外,它看起来很稳固。