我有一个 Task 实体,它有一个前面和后面的任务:
namespace OneToOneIssue.Domain
{
public class Task
{
public virtual Guid Id { get; set; }
public virtual string Description { get; set; }
public virtual Task FollowingTask { get; set; }
public virtual Task PrecedingTask { get; set; }
}
}
数据库表如下所示:
CREATE TABLE [dbo].[Task](
[Id] uniqueidentifier NOT NULL,
[Description] nvarchar(100) NULL,
[FollowingTaskId] uniqueidentifier NULL
CONSTRAINT [PK_Task] 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]
INSERT INTO [Task] ([Id], [Description], [FollowingTaskId]) VALUES ('30efbfda-f3b5-42fb-906e-098fb32be79d', 'Task 1', 'f7367187-406d-47db-931e-b9e4fa8a4774')
INSERT INTO [Task] ([Id], [Description], [FollowingTaskId]) VALUES ('f7367187-406d-47db-931e-b9e4fa8a4774', 'Task 2', '42c25da5-7c04-4adc-a9c2-6bf8a9ff5c89')
INSERT INTO [Task] ([Id], [Description], [FollowingTaskId]) VALUES ('42c25da5-7c04-4adc-a9c2-6bf8a9ff5c89', 'Task 3', NULL)
INSERT INTO [Task] ([Id], [Description], [FollowingTaskId]) VALUES ('ffe58f51-bb85-4681-af9d-d232326a30e4', 'Task 4', 'ba2ee26c-ebbb-4d7e-a596-40db9f0711c4')
INSERT INTO [Task] ([Id], [Description], [FollowingTaskId]) VALUES ('ba2ee26c-ebbb-4d7e-a596-40db9f0711c4', 'Task 5', '29189134-8be9-4d93-873e-ce5efefe1c1a')
INSERT INTO [Task] ([Id], [Description], [FollowingTaskId]) VALUES ('29189134-8be9-4d93-873e-ce5efefe1c1a', 'Task 6', NULL)
INSERT INTO [Task] ([Id], [Description], [FollowingTaskId]) VALUES ('ef069d0a-f2a8-4c9a-8bbc-99ee1e0e2991', 'Task 7', '56a6eb57-ab9f-49cb-875a-a072158b0265')
INSERT INTO [Task] ([Id], [Description], [FollowingTaskId]) VALUES ('56a6eb57-ab9f-49cb-875a-a072158b0265', 'Task 8', 'f8b7cc9b-269e-44c7-85bf-44592d70a21e')
INSERT INTO [Task] ([Id], [Description], [FollowingTaskId]) VALUES ('f8b7cc9b-269e-44c7-85bf-44592d70a21e', 'Task 9', NULL)
和这样的映射:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
namespace="OneToOneIssue.Domain"
assembly="OneToOneIssue.Domain">
<class name="Task" table="`Task`">
<id name="Id" column="Id" type="guid">
<generator class="assigned"/>
</id>
<property name="Description" column="`Description`" />
<many-to-one name="FollowingTask" class="Task" column="FollowingTaskId" />
<one-to-one name="PrecedingTask" class="Task" property-ref="FollowingTask" />
</class>
</hibernate-mapping>
现在,如果我运行查询以获取任务 2、5 和 8(唯一具有如下任务的任务:
var tasks = session
.CreateCriteria<Task>()
.Add(Restrictions.In("Description", new string[] {"Task 2", "Task 5", "Task 8"}))
.List<Task>();
然后我得到了我期望的主要查询,还有一个针对所有前面任务的查询:
exec sp_executesql N'SELECT this_.Id as Id0_1_, this_.[Description] as Descript2_0_1_, this_.FollowingTaskId as Followin3_0_1_, task2_.Id as Id0_0_, task2_.[Description] as Descript2_0_0_, task2_.FollowingTaskId as Followin3_0_0_ FROM [Task] this_ left outer join [Task] task2_ on this_.Id=task2_.FollowingTaskId WHERE this_.[Description] in (@p0, @p1, @p2)',N'@p0 nvarchar(4000),@p1 nvarchar(4000),@p2 nvarchar(4000)',@p0=N'Task 2',@p1=N'Task 5',@p2=N'Task 8'
exec sp_executesql N'SELECT task0_.Id as Id0_1_, task0_.[Description] as Descript2_0_1_, task0_.FollowingTaskId as Followin3_0_1_, task1_.Id as Id0_0_, task1_.[Description] as Descript2_0_0_, task1_.FollowingTaskId as Followin3_0_0_ FROM [Task] task0_ left outer join [Task] task1_ on task0_.Id=task1_.FollowingTaskId WHERE task0_.FollowingTaskId=@p0',N'@p0 uniqueidentifier',@p0='FFE58F51-BB85-4681-AF9D-D232326A30E4'
exec sp_executesql N'SELECT task0_.Id as Id0_1_, task0_.[Description] as Descript2_0_1_, task0_.FollowingTaskId as Followin3_0_1_, task1_.Id as Id0_0_, task1_.[Description] as Descript2_0_0_, task1_.FollowingTaskId as Followin3_0_0_ FROM [Task] task0_ left outer join [Task] task1_ on task0_.Id=task1_.FollowingTaskId WHERE task0_.FollowingTaskId=@p0',N'@p0 uniqueidentifier',@p0='EF069D0A-F2A8-4C9A-8BBC-99EE1E0E2991'
exec sp_executesql N'SELECT task0_.Id as Id0_1_, task0_.[Description] as Descript2_0_1_, task0_.FollowingTaskId as Followin3_0_1_, task1_.Id as Id0_0_, task1_.[Description] as Descript2_0_0_, task1_.FollowingTaskId as Followin3_0_0_ FROM [Task] task0_ left outer join [Task] task1_ on task0_.Id=task1_.FollowingTaskId WHERE task0_.FollowingTaskId=@p0',N'@p0 uniqueidentifier',@p0='30EFBFDA-F3B5-42FB-906E-098FB32BE79D'
我什至不需要加载前面的任务。
急切地加载前面的任务也无济于事。
如果我将FollowingTask 和PrecedingTask 设置为lazy="proxy" 也无济于事。如果删除一对一映射确实可以解决问题,但这不是一个可能的解决方案。
如果您需要一对一映射,我在这里看到了有关解决问题的问题,答案似乎是它是一个错误,您只需要忍受它。但是,我什至不需要加载它。我从不访问它,它只是无缘无故地加载。我相信这个问题也是独一无二的,因为关系的递归性质。
有什么方法可以阻止它加载,还是有另一种方法可以完全实现相同的目标?