このシナリオでは、コードによるマッピングを使用して 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 テーブルに挿入されます。
問題は、1 つ以上を挿入した後にプロジェクトのプロジェクト リンクを照会しようとすると、次の例外が発生することです。
指定された識別子を持つ複数の行が見つかりました: 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 エンティティからのものです。