对实体A的查询不会返回相关实体B的子类数据
本文关键字:实体 子类 数据 查询 返回 | 更新日期: 2023-09-27 18:01:25
我有一个叫做WorkflowTask的类,它包含一个TaskProperties类属性。有许多使用JoinedSubclassMapping(比如DeliveryTaskProperties)映射的TaskProperties子类。
我需要执行像下面这样的NHibernate查询来获得我需要处理的工作流任务列表:
NHibernateSession.Query<WorkflowTask>().Where(x => (x.WorkflowTaskStatus == WorkflowTask.WorkflowTaskStatuses.New && x.TaskProperties.UserAssignedTo=="System")).ToList<WorkflowTask>();
当遍历这个列表时,我注意到TaskProperties的正确子类被识别出来了。然而,当我试图将wt.TaskProperties转换为DeliveryTaskProperties以访问其数据时,我得到了一个无效的转换异常。我能让它工作的唯一方法是通过指定确切的子类来尝试再次加载任务属性实体:
下面的工作,我可以转换到DeliveryTaskProperties类:
wt.TaskProperties = NHibernateSession.Load<DeliveryTaskProperties>(wt.TaskProperties.Id);
直接的窗口:
{Workflow.Entities.DeliveryTaskProperties}
[DeliveryTaskPropertiesProxy]: {Workflow.Entities.DeliveryTaskProperties}
基础:{Workflow.Entities.DeliveryTaskProperties}
UserAssignedTo:"系统"
这不起作用,我得到一个无效的强制转换异常:
wt.TaskProperties = NHibernateSession.Load<TaskProperties>(wt.TaskProperties.Id);
直接的窗口:
{Workflow.Entities.DeliveryTaskProperties}
[TaskPropertiesProxy]: {Workflow.Entities.DeliveryTaskProperties}
基础:{Workflow.Entities.DeliveryTaskProperties}
UserAssignedTo:"系统"
类映射:
public class WorkflowTaskMapping : BaseWorkflowEntityMapping<WorkflowTask>
{
public WorkflowTaskMapping()
{
this.Property(x => x.TaskPropertiesId, map =>
{
map.Column("TaskPropertiesId");
map.Insert(false);
map.Update(false);
map.NotNullable(true);
});
this.ManyToOne<TaskProperties>(x => x.TaskProperties, map =>
{
map.Column("TaskPropertiesId");
map.Cascade(Cascade.All);
map.NotNullable(true);
map.ForeignKey("WFTaskProperties_WFTask_FK");
});
this.Property(x => x.WorkflowTaskStatus, map => map.NotNullable(true));
}
}
public class TaskPropertiesMapping : BaseWorkflowEntityMapping<TaskProperties>
{
public TaskPropertiesMapping()
{
this.Property(x => x.UserAssignedTo, map => map.NotNullable(true));
}
}
public class DeliveryTaskPropertiesMapping : JoinedSubclassMapping<DeliveryTaskProperties>
{
public DeliveryTaskPropertiesMapping()
{
this.Key(x => { x.Column("Id"); x.ForeignKey("DelivTask_TaskProperties_FK"); });
this.Property(x => x.DeliveryAddress, map => map.NotNullable(true));
this.Property(x => x.Deadline, map => map.NotNullable(true));
this.Property(x => x.DeliveryOnDeadline, map => map.NotNullable(true));
}
}
是否有一种方法可以在加载WorkflowTask实体时正确加载子类数据,而不必指定确切的子类类型?
好了,我明白了。虽然在我读到的处理类似问题的其他帖子中不是很清楚,但似乎Eager抓取为我做到了这一点。
如果我改变我的查询并像这样添加抓取:
NHibernateSession.Query<WorkflowTask>().Where(x => (x.WorkflowTaskStatus == WorkflowTask.WorkflowTaskStatuses.New && x.TaskProperties.UserAssignedTo == "System")).Fetch(x => x.TaskProperties).ToList<WorkflowTask>();
然后nhibernate实际上在内存中加载子类,尽管类型仍然是基类的类型。这允许稍后对子类进行强制转换以访问其属性。
我不确定这是否是你需要的:
TaskProperties tpAlias = null;
var workflowTasks = NHibernateSession.QueryOver<WorkflowTask>()
.Left.JoinAlias(x => x.TaskProperties, () => tpAlias)
.Where(x => (x.WorkflowTaskStatus == WorkflowTask.WorkflowTaskStatuses.New
&& x.TaskProperties.UserAssignedTo == "System"))
.List();