NHibernate - 基于类型列的渴望加载一对多关系
NHibernate - Eager load one-to-many relationship on the basis of type column
我需要从同一个 table 加载三个一对多关系到其他三个 table。以下是我的 table:
的 ERD
ProcessActionLog是与ProcessActionEmail、三个一对多关系的table基于 ProcessActionType 列的 ProcessActionInterviewFeedback 和 ProcessActionNotesInfo tables 将包含以下列的名称我对这些 table 的映射:
1) ProcessActionLog Table 映射:
class ProcessActionLogMap : ClassMap<ProcessActionLog>
{
public ProcessActionLogMap()
{
//Rest of mappings//
HasMany(x => x.ProcessActionEmail).Cascade.SaveUpdate().Inverse();
HasMany(x => x.ProcessActionInterviewFeedback).Cascade.SaveUpdate().Inverse();
HasMany(x => x.ProcesssActionNotesInfo).Cascade.SaveUpdate().Inverse();
}
2) ProcessActionEmailMapping:
class ProcessActionEmailMap : ClassMap<ProcessActionEmail>
{
public ProcessActionEmailMap()
{
//rest of mappings//
References(x => x.ProcessActionLog, "ProcessActionLogId");
}
}
3) ProcessActionInterviewFeedback 映射:
class ProcessActionInterviewFeedbackMap : ClassMap<ProcessActionInterviewFeedback>
{
public ProcessActionInterviewFeedbackMap()
{
//Rest of mappings//
References(x => x.ProcessActionLog, "ProcessActionLogId");
}
}
4) ProcessActionNotesInfo
class ProcessActionNotesInfoMap : ClassMap<ProcessActionNotesInfo>
{
public ProcessActionNotesInfoMap()
{
//Rest of mappings//
References(x => x.ProcessActionLog, "ProcessActionLogId");
}
}
现在我尝试了以下查询,以便预先加载所有三个关系:
public IList<ProcessActionLog> FetchUserSpecificProcessActionLogs(int UserId)
{
return _session.Query<ProcessActionLog>()
.Where(x => x.MasterUser.Id == UserId)
.Fetch(x => x.ProcessActionEmail)
.Fetch(x => x.ProcessActionInterviewFeedback)
.Fetch(x => x.ProcesssActionNotesInfo)
.ToFuture().ToList<ProcessActionLog>();
}
但这给了我以下错误:
Cannot simultaneously fetch multiple bags.
请帮助我解决此问题或建议我可以使用 ProcessActionLog Table 的 processActionType 列急切加载实体的任何其他方法。谢谢。
最后,通过在映射中使用 ISet 而不是 IList 解决了这个问题,现在我的代码如下:
ProcessActionLog 实体
public class ProcessActionLog
{
/// <summary>
/// Process Action Emails
/// </summary>
private ISet<ProcessActionEmail> _ProcessActionEmail { get; set; }
/// <summary>
/// Process Action Interview Feedbacks
/// </summary>
private ISet<ProcessActionInterviewFeedback> _ProcessActionInterviewFeedback { get; set; }
/// <summary>
/// Process action notes info
/// </summary>
private ISet<ProcessActionNotesInfo> _ProcessActionNotesInfo { get; set; }
/// <summary>
/// Is process action email
/// </summary>
public virtual bool IsProcessActionEmail
{
get { return ProcessActionType == ProcessActionType.ProcessActionEmail; }
}
/// <summary>
/// Is process action interview feedback
/// </summary>
public virtual bool IsProcessActionInterviewFeedback
{
get { return ProcessActionType == ProcessActionType.ProcessActionInterviewFeedback; }
}
/// <summary>
/// Is process action notes info
/// </summary>
public virtual bool IsProcessActionNotesInfo
{
get { return ProcessActionType == ProcessActionType.ProcessActionNotesInfo; }
}
/// <summary>
/// Process Action Log setter and getter
/// </summary>
public virtual ISet<ProcessActionEmail> ProcessActionEmail
{
get { return (IsProcessActionEmail ? _ProcessActionEmail : null); }
set { _ProcessActionEmail = value; }
}
/// <summary>
/// Process Action Interview Feedback setter and getter
/// </summary>
public virtual ISet<ProcessActionInterviewFeedback> ProcessActionInterviewFeedback
{
get { return (IsProcessActionInterviewFeedback ? _ProcessActionInterviewFeedback : null); }
set { _ProcessActionInterviewFeedback = value; }
}
/// <summary>
/// Process Action Notes info setter and getter
/// </summary>
public virtual ISet<ProcessActionNotesInfo> ProcessActionNotesInfo
{
get { return (IsProcessActionNotesInfo ? _ProcessActionNotesInfo : null); }
set { _ProcessActionNotesInfo = value; }
}
}
ProcessActionEmail 实体
public class ProcessActionEmail
{
//Rest of the attributes
/// <summary>
/// Process Action log of this particular email
/// </summary>
public virtual ProcessActionLog ProcessActionLog { get; set; }
ProcessActionInterviewFeedback 实体
public class ProcessActionInterviewFeedback
{
/// <summary>
/// Process Action Log
/// </summary>
public virtual ProcessActionLog ProcessActionLog { get; set; }
}
ProcessActionLog 映射
class ProcessActionLogMap : ClassMap<ProcessActionLog>
{
public ProcessActionLogMap()
{
Id(x => x.Id);
Map(x => x.LogName).Length(100).Not.Nullable();
Map(x => x.ProcessActionType).CustomType<Int32>().Not.Nullable();
Map(x => x.CreatedAt).CustomType<DateTime>().Not.Nullable();
References(x => x.MasterUser).Column("UserId");
References(x => x.Process).Column("ProcessId");
References(x => x.SystemUser).Column("CreatedBy");
References(x => x.Task).Column("TaskId").Nullable();
HasMany(x => x.ProcessActionEmail).Cascade.SaveUpdate().Inverse();
HasMany(x => x.ProcessActionInterviewFeedback).Cascade.SaveUpdate().Inverse();
HasMany(x => x.ProcessActionNotesInfo).Cascade.SaveUpdate().Inverse();
}
}
并且查询与问题中的相同。
我需要从同一个 table 加载三个一对多关系到其他三个 table。以下是我的 table:
的 ERDProcessActionLog是与ProcessActionEmail、三个一对多关系的table基于 ProcessActionType 列的 ProcessActionInterviewFeedback 和 ProcessActionNotesInfo tables 将包含以下列的名称我对这些 table 的映射:
1) ProcessActionLog Table 映射:
class ProcessActionLogMap : ClassMap<ProcessActionLog>
{
public ProcessActionLogMap()
{
//Rest of mappings//
HasMany(x => x.ProcessActionEmail).Cascade.SaveUpdate().Inverse();
HasMany(x => x.ProcessActionInterviewFeedback).Cascade.SaveUpdate().Inverse();
HasMany(x => x.ProcesssActionNotesInfo).Cascade.SaveUpdate().Inverse();
}
2) ProcessActionEmailMapping:
class ProcessActionEmailMap : ClassMap<ProcessActionEmail>
{
public ProcessActionEmailMap()
{
//rest of mappings//
References(x => x.ProcessActionLog, "ProcessActionLogId");
}
}
3) ProcessActionInterviewFeedback 映射:
class ProcessActionInterviewFeedbackMap : ClassMap<ProcessActionInterviewFeedback>
{
public ProcessActionInterviewFeedbackMap()
{
//Rest of mappings//
References(x => x.ProcessActionLog, "ProcessActionLogId");
}
}
4) ProcessActionNotesInfo
class ProcessActionNotesInfoMap : ClassMap<ProcessActionNotesInfo>
{
public ProcessActionNotesInfoMap()
{
//Rest of mappings//
References(x => x.ProcessActionLog, "ProcessActionLogId");
}
}
现在我尝试了以下查询,以便预先加载所有三个关系:
public IList<ProcessActionLog> FetchUserSpecificProcessActionLogs(int UserId)
{
return _session.Query<ProcessActionLog>()
.Where(x => x.MasterUser.Id == UserId)
.Fetch(x => x.ProcessActionEmail)
.Fetch(x => x.ProcessActionInterviewFeedback)
.Fetch(x => x.ProcesssActionNotesInfo)
.ToFuture().ToList<ProcessActionLog>();
}
但这给了我以下错误:
Cannot simultaneously fetch multiple bags.
请帮助我解决此问题或建议我可以使用 ProcessActionLog Table 的 processActionType 列急切加载实体的任何其他方法。谢谢。
最后,通过在映射中使用 ISet 而不是 IList 解决了这个问题,现在我的代码如下:
ProcessActionLog 实体
public class ProcessActionLog
{
/// <summary>
/// Process Action Emails
/// </summary>
private ISet<ProcessActionEmail> _ProcessActionEmail { get; set; }
/// <summary>
/// Process Action Interview Feedbacks
/// </summary>
private ISet<ProcessActionInterviewFeedback> _ProcessActionInterviewFeedback { get; set; }
/// <summary>
/// Process action notes info
/// </summary>
private ISet<ProcessActionNotesInfo> _ProcessActionNotesInfo { get; set; }
/// <summary>
/// Is process action email
/// </summary>
public virtual bool IsProcessActionEmail
{
get { return ProcessActionType == ProcessActionType.ProcessActionEmail; }
}
/// <summary>
/// Is process action interview feedback
/// </summary>
public virtual bool IsProcessActionInterviewFeedback
{
get { return ProcessActionType == ProcessActionType.ProcessActionInterviewFeedback; }
}
/// <summary>
/// Is process action notes info
/// </summary>
public virtual bool IsProcessActionNotesInfo
{
get { return ProcessActionType == ProcessActionType.ProcessActionNotesInfo; }
}
/// <summary>
/// Process Action Log setter and getter
/// </summary>
public virtual ISet<ProcessActionEmail> ProcessActionEmail
{
get { return (IsProcessActionEmail ? _ProcessActionEmail : null); }
set { _ProcessActionEmail = value; }
}
/// <summary>
/// Process Action Interview Feedback setter and getter
/// </summary>
public virtual ISet<ProcessActionInterviewFeedback> ProcessActionInterviewFeedback
{
get { return (IsProcessActionInterviewFeedback ? _ProcessActionInterviewFeedback : null); }
set { _ProcessActionInterviewFeedback = value; }
}
/// <summary>
/// Process Action Notes info setter and getter
/// </summary>
public virtual ISet<ProcessActionNotesInfo> ProcessActionNotesInfo
{
get { return (IsProcessActionNotesInfo ? _ProcessActionNotesInfo : null); }
set { _ProcessActionNotesInfo = value; }
}
}
ProcessActionEmail 实体
public class ProcessActionEmail
{
//Rest of the attributes
/// <summary>
/// Process Action log of this particular email
/// </summary>
public virtual ProcessActionLog ProcessActionLog { get; set; }
ProcessActionInterviewFeedback 实体
public class ProcessActionInterviewFeedback
{
/// <summary>
/// Process Action Log
/// </summary>
public virtual ProcessActionLog ProcessActionLog { get; set; }
}
ProcessActionLog 映射
class ProcessActionLogMap : ClassMap<ProcessActionLog>
{
public ProcessActionLogMap()
{
Id(x => x.Id);
Map(x => x.LogName).Length(100).Not.Nullable();
Map(x => x.ProcessActionType).CustomType<Int32>().Not.Nullable();
Map(x => x.CreatedAt).CustomType<DateTime>().Not.Nullable();
References(x => x.MasterUser).Column("UserId");
References(x => x.Process).Column("ProcessId");
References(x => x.SystemUser).Column("CreatedBy");
References(x => x.Task).Column("TaskId").Nullable();
HasMany(x => x.ProcessActionEmail).Cascade.SaveUpdate().Inverse();
HasMany(x => x.ProcessActionInterviewFeedback).Cascade.SaveUpdate().Inverse();
HasMany(x => x.ProcessActionNotesInfo).Cascade.SaveUpdate().Inverse();
}
}
并且查询与问题中的相同。