您是如何得出项目具有依赖关系的?你只声明你有一个表,所以我假设实际上没有一个名为 ProjectDependency 的表。
但是,如果有这样的表,它可能是多余的。如果只有 Project 表,那就更简单了。忍受我:
如果是我并且我能够修改表,我会让 Project 有一个自引用(递归)外键。这样该项目表将有一个名为 ParentProjectId 的列,其类型与表项目的主键相同,然后将主键作为外键约束引用。
类似这样的东西(这是用于 ms-sql 服务器的,但这个概念应该存在于其他数据库中,如果不让我知道的话):
CREATE TABLE [dbo].[Project](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NULL,
[ParentProjectId] [int] NULL,
CONSTRAINT [PK_Project] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Project] WITH CHECK ADD CONSTRAINT [FK_ParentProject_Project] FOREIGN KEY([ParentProjectId])
REFERENCES [dbo].[Project] ([Id])
GO
ALTER TABLE [dbo].[Project] CHECK CONSTRAINT [FK_ParentProject_Project]
GO
如果可能的话,我会按照以下方式建模:
public class Project
{
private IList<Project> _dependencies;
public virtual int? Id { get; set; }
public virtual string Name { get; set; }
public virtual IList<Project> Dependencies
{
get { return _dependencies ?? (_dependencies = new List<Project>()); }
set { _dependencies = value; }
}
public virtual Project ParentProject { get; set; }
public virtual Project AddDependency(Project dependency)
{
dependency.ParentProject = this;
Dependencies.Add(dependency);
return this;
}
}
然后在映射中我会这样映射(暂时是伪代码,将更新):
public sealed class ProjectMap : ClassMap<Project>
{
public ProjectMap()
{
Id(x => x.Id).Column("Id").GeneratedBy.Native();
Map(x => x.Name);
References(x => x.ParentProject).Column("ParentProjectId").Cascade.All();
HasMany(x => x.Dependencies).KeyColumn("ParentProjectId").Inverse().Cascade.AllDeleteOrphan();
}
}
这基本上使您能够使用递归无限地嵌套项目。
现在,根据您的问题,您正在使用 nhibernate,并且您的项目实体具有 int 类型的主键。通常我也会将该键设为标识列,并且我上面的映射让 nhibernate 知道数据库将生成它。
仅基于您询问“最优雅的方式”是否是我的帖子,基于您的模型,并假设我有能力/权限使用数据库架构,这就是我的做法。
AddDependency 方法的工作方式是它处理将依赖项连接到项目,当您实际对项目实体执行 Session.Save 时,NHibernate 实际上只会插入那些新项目。我会简单地创建或选择新项目并将它们传递进来,而不是尝试使用 id,然后让数据库处理它(因为它擅长它)
我可能不会尝试做多对多,但如果这是你真正需要的,请告诉我,我会更新我的答案。我只是说你有'我的 SQL 服务器数据库中有一个表'
第