对于这种情况,我正在尝试使用按代码映射来建立 NHibernate 映射:
我有一个实体项目,它可以包含其他项目的列表。
所以我的项目实体看起来像这样:
public class Project : EntityBase
{
public Project()
{
}
public virtual string Name { get; set; }
public virtual string Client { get; set; }
public virtual string Description { get; set; }
private readonly IList<Project> _projectLinks = new List<Project>();
public virtual IList<Project> ProjectLinks
{
get { return _projectLinks; }
}
}
我的数据库表如下所示:
CREATE TABLE [dbo].[Project](
[Id] [uniqueidentifier] NOT NULL,
[Name] [nvarchar](255) NOT NULL,
[Description] [nvarchar](MAX) NULL,
[Client] [nvarchar](255) NULL....
CREATE TABLE [dbo].[ProjectLink](
[ProjectId] [uniqueidentifier] NOT NULL,
[LinkedProjectId] [uniqueidentifier] NOT NULL
ProjectId 和 LinkedProjectId 都有返回 Project.ProjectId 的外键
我的映射如下所示:
public class ProjectMapping : ClassMapping<Project>
{
public ProjectMapping()
{
Bag(x => x.ProjectLinks,
collectionMapping =>
{
collectionMapping.Table("ProjectLink");
collectionMapping.Cascade(Cascade.None);
collectionMapping.Key(k => k.Column("ProjectId"));
},
map => map.ManyToMany(p => p.Column("LinkedProjectId")));
这是基于以下帖子的答案:
这使我可以将项目链接添加到我的项目中,并且当我提交它们时,它们会毫无问题地插入到我的 ProjectLinks 表中。
问题是,当我在插入一个或多个后尝试查询项目的项目链接时,出现以下异常:
找到了多行具有给定标识符的行:b1fb7034-ee00-4f6a-98d7-35a39a15a0c2,对于类:My.Project
仅当给定项目存在 ProjectLinks 时才会引发此异常。上面的 Id 位于 ProjectLink 条目的 LinkedProjectId 列中。如果我添加了 N 个项目链接,则始终为 ProjectLink 表中的第一个 LinkedProjectId 引发此异常。
关于如何正确建立此映射的任何想法?
更新:
调用 _session.Get(_currentRequest.ProjectId).ProjectLinks 时会生成以下 SQL:
SELECT
project0_.Id as Id10_5_, project0_.Version as Version10_5_, project0_.Name as Name10_5_, project0_.Client as Client10_5_, project0_.Description as Descript5_10_5_, project0_.ProjectType as ProjectT6_10_5_, project0_.IsSalesTaxApplied as IsSalesT7_10_5_, project0_.SalesTaxRate as SalesTax8_10_5_, project0_.SalesTaxName as SalesTax9_10_5_, project0_.TermsAndConditions as TermsAn10_10_5_, directcost1_.Id as Id3_0_, directcost1_.Version as Version3_0_, directcost1_.ProjectId as ProjectId3_0_, resourcesc2_.Id as Id8_1_, resourcesc2_.Version as Version8_1_, resourcesc2_.ProjectId as ProjectId8_1_, margin3_.Id as Id6_2_, margin3_.Version as Version6_2_, margin3_.OverallMarginPercentage as OverallM3_6_2_, margin3_.CorporateMarginPercentage as Corporat4_6_2_, margin3_.ProvisionalSumsMarginPercentage as Provisio5_6_2_, margin3_.FixedMargin as FixedMar6_6_2_, margin3_.OverallMarginCalculationType as OverallM7_6_2_, margin3_.CorporateMarginCalculationType as Corporat8_6_2_, project4_.Id as Id10_3_, project4_.Version as Version10_3_, project4_.Name as Name10_3_, project4_.Client as Client10_3_, project4_.Description as Descript5_10_3_, project4_.ProjectType as ProjectT6_10_3_, project4_.IsSalesTaxApplied as IsSalesT7_10_3_, project4_.SalesTaxRate as SalesTax8_10_3_, project4_.SalesTaxName as SalesTax9_10_3_, project4_.TermsAndConditions as TermsAn10_10_3_, spreadopti5_.Id as Id12_4_, spreadopti5_.Version as Version12_4_, spreadopti5_.AlwaysRoundupSellRates as AlwaysRo3_12_4_
FROM
Project project0_
left outer join CostSchedule directcost1_ on project0_.Id=directcost1_.ProjectId and directcost1_.Discriminator=''DCS''
left outer join ResourceSchedule resourcesc2_ on project0_.Id=resourcesc2_.ProjectId
left outer join Margin margin3_ on project0_.Id=margin3_.Id
left outer join Project project4_ on margin3_.Id=project4_.Id
left outer join SpreadOptions spreadopti5_ on project4_.Id=spreadopti5_.Id
WHERE
project0_.Id=@p0',N'@p0 uniqueidentifier',@p0='0F91D16E-0D35-444C-93FF-C0C696C7BE58'
随着
SELECT
projectlin0_.ProjectId as ProjectId6_, projectlin0_.LinkedProjectId as LinkedPr2_6_, project1_.Id as Id10_0_, project1_.Version as Version10_0_, project1_.Name as Name10_0_, project1_.Client as Client10_0_, project1_.Description as Descript5_10_0_, project1_.ProjectType as ProjectT6_10_0_, project1_.IsSalesTaxApplied as IsSalesT7_10_0_, project1_.SalesTaxRate as SalesTax8_10_0_, project1_.SalesTaxName as SalesTax9_10_0_, project1_.TermsAndConditions as TermsAn10_10_0_, directcost2_.Id as Id3_1_, directcost2_.Version as Version3_1_, directcost2_.ProjectId as ProjectId3_1_, resourcesc3_.Id as Id8_2_, resourcesc3_.Version as Version8_2_, resourcesc3_.ProjectId as ProjectId8_2_, margin4_.Id as Id6_3_, margin4_.Version as Version6_3_, margin4_.OverallMarginPercentage as OverallM3_6_3_, margin4_.CorporateMarginPercentage as Corporat4_6_3_, margin4_.ProvisionalSumsMarginPercentage as Provisio5_6_3_, margin4_.FixedMargin as FixedMar6_6_3_, margin4_.OverallMarginCalculationType as OverallM7_6_3_, margin4_.CorporateMarginCalculationType as Corporat8_6_3_, project5_.Id as Id10_4_, project5_.Version as Version10_4_, project5_.Name as Name10_4_, project5_.Client as Client10_4_, project5_.Description as Descript5_10_4_, project5_.ProjectType as ProjectT6_10_4_, project5_.IsSalesTaxApplied as IsSalesT7_10_4_, project5_.SalesTaxRate as SalesTax8_10_4_, project5_.SalesTaxName as SalesTax9_10_4_, project5_.TermsAndConditions as TermsAn10_10_4_, spreadopti6_.Id as Id12_5_, spreadopti6_.Version as Version12_5_, spreadopti6_.AlwaysRoundupSellRates as AlwaysRo3_12_5_
FROM
ProjectLink projectlin0_
left outer join Project project1_ on projectlin0_.LinkedProjectId=project1_.Id
left outer join CostSchedule directcost2_ on project1_.Id=directcost2_.ProjectId and directcost2_.Discriminator=''DCS''
left outer join ResourceSchedule resourcesc3_ on project1_.Id=resourcesc3_.ProjectId
left outer join Margin margin4_ on project1_.Id=margin4_.Id
left outer join Project project5_ on margin4_.Id=project5_.Id
left outer join SpreadOptions spreadopti6_ on project5_.Id=spreadopti6_.Id
WHERE
projectlin0_.ProjectId=@p0',N'@p0 uniqueidentifier',@p0='0F91D16E-0D35-444C-93FF-C0C696C7BE58'
我试图让示例保持简单,上面生成的 SQL 来自完整的 Project 实体。