C# NHibernate:避免N+;1在映射中使用基类时出现的问题
我有以下情况:C# NHibernate:避免N+;1在映射中使用基类时出现的问题,c#,nhibernate,nhibernate-mapping,C#,Nhibernate,Nhibernate Mapping,我有以下情况: Session类有许多ProcessableItems,而SqlTask是从ProcessableItem类派生的。 SqlTask可以有许多变量(propertySqlTaskInputParameters,SqlParameterVariable类;有些任务没有变量) 该点在会话类中,可处理项(不是任务本身)用作导航属性: public class Session { [DataMember] public virtual IList<Processa
Session
类有许多ProcessableItem
s,而SqlTask
是从ProcessableItem
类派生的。
SqlTask
可以有许多变量(propertySqlTaskInputParameters
,SqlParameterVariable
类;有些任务没有变量)
该点在会话
类中,可处理项
(不是任务本身)用作导航属性:
public class Session
{
[DataMember]
public virtual IList<ProcessableItem> ProcessableItems
{
get { return this._items; }
set { this._items = value; }
}
}
public SessionMap()
{
HasMany(t => t.ProcessableItems)
}
public class ProcessableItem
{
...
}
public class SqlTask : ProcessableItem
{
[DataMember]
public virtual IList<SqlParameterVariable> SqlTaskInputParameters { get; set; };
}
不能急于加载派生类的关系 在您的情况下,您甚至不应该这样做,因为您似乎已经在获取另一个集合(
ChildsOnSuccess
),在这里获取另一个集合将导致它们之间的笛卡尔积,从而导致结果重复。(这是一个NHibernate限制。)
好消息是,解决N+1问题除了急切获取之外,还有其他方法
- 保持延迟加载,但启用。我已经做了一些详细的解释
- 使用。但是,这就是缓存,所以最好从另一个开始,如果稍后添加二级缓存,这仍然是有益的
var query = session.Query<ETLSession>()
.Where(s => s.Id == request.IdETLSession);
query.FetchMany(s => s.ProcessableItems)
.ThenFetch(p => p.ChildsOnSuccess).ToFuture();
Session session = query.ToFuture().ToList().First();