我有以下课程
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
Id
和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。 除此之外,它看起来很稳固。