2

对于这种情况,我正在尝试使用按代码映射来建立 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")));

这是基于以下帖子的答案:

NHibernate 3.2 多对多代码映射

这使我可以将项目链接添加到我的项目中,并且当我提交它们时,它们会毫无问题地插入到我的 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 实体。

4

1 回答 1

0

我的猜测是,外部连接中的一个会产生多个结果,并且会混淆多对多初始化。尝试延迟加载 Schedules, Margin 来验证

于 2012-08-16T11:53:42.147 回答