让我们选择一个示例模型作为参考:
public class Cat{
public long Id;
public string Name;
public IEnumerable<Cat> Friends; //ManyToMany
}
请注意,这是我能描述的最简单的模型。
目前,为了使用Cat
插入新的Friends
,我必须首先获取其完整的持久对象。例如..
Cat sally = Repository.GetByName("Sally").First(); //The first cat named Sally
Cat mary = new Cat{ Name="Mary, Friends = new Cat[] {sally} };
Repository.Save(mary); //Which is Session.Save(mary);
只要莎莉在当前范围内,这样就可以正常工作。但是在Web环境中,考虑到我在MVC中工作,我不一定将所有持久化对象保留在内存中。想想我可以创建新猫的页面,并从多选列表中选择孩子......
如果MVC控制器只返回猫的ID(这就是我想要的),我不能做以下情况,否则我会得到重复的条目异常
Cat mary = new Cat{ Name="Mary, Friends = new Cat[] {new Cat{ Id = 1}, new Cat{Id=2}... };
Repository.Save(mary); //Boom, because it tries to persist the new children with duplicate IDs
相反,我必须
long[] ids;
IEnumerable<Cat> friends = from cat in Repository.Query() where Id in ids select cat; //Which does a SELECT query
Cat mary = new Cat{ Name="Mary", Friends = friends };
Repository.Save(mary); //Which runs fine;
现在我的问题是:鉴于在某个时间我知道已经存在的对象集合的主键,我如何插入一个新对象,该对象具有对集合对象的引用没有查询数据库以获取所有内容?
我知道NHibernate有缓存,因此经常查询Session
已知ID并不会触发完整查询,但我想更多地了解NHibernate的强大功能。
由于问题是出于示例目的,请不要介意我是否不关心反向关系。
答案 0 :(得分:1)
由于你有id,所以你需要做的只是使用session.Load
来获取引用而不从db加载它们。
只需将第二行更改为以下内容:
var friends = from id in ids select session.Load<Cat>(id);