我有一个根对象,它有一个集合属性。
例如:
I have a Shelf object that has Books.
// Now
public class Shelf
{
public ICollection<Book> Books {get; set;}
}
// Want
public class Shelf
{
public IQueryable<Book> Books {get;set;}
}
我想要完成的是返回一个 IQueryable 集合,这样我就可以直接从父集合运行分页和过滤。
var shelf = shelfRepository.Get(1);
var filtered = from book in shelf.Books
where book.Name == "The Great Gatsby"
select book;
我想让 NHibernate 专门执行该查询,而不是让 get all 加载整个集合,然后在内存中解析它(这是我使用 ICollection 时当前发生的情况)。
这背后的原因是我的集合可能很大,有数万条记录,而获取所有查询可能会破坏我的数据库。
我想隐式地执行此操作,以便当 NHibernate 在我的类中看到 IQueryable 时,它知道该做什么。
我查看了 NHibernate 的 LINQ 提供程序,目前我正在决定采用大型集合并将它们拆分到它们自己的存储库中,以便我可以明确调用过滤和分页。
LINQ To SQL 提供了与我所说的类似的东西。
最佳答案
我一直在尝试为类似的问题提出解决方案。
您可以使用 ISession.FilterCollection
从实体中过滤集合。这将创建一个额外的 IQuery,您可以在其中进行计数、分页、添加条件等操作。
因此,例如(我在 FilterCollection 中的查询可能有点偏离,但您应该明白了):
ISession session = GetSession();
var shelf = session.Get<Shelf>(id);
var books = session.FilterCollection(shelf.Books, "where Name = :title").SetString("title", "The Great Gatsby").List<Book>();
但是有一个问题:
- 执行代码的消费者 需要访问 ISession.CreateFilter,或者你需要 在你的上创建一个方法 接收属性的存储库, 查询和您的查询参数 (以及任何传呼或其他 信息)。不是最性感的 地球上的东西。
- 这不是您想要的 LINQ。
不幸的是,我认为没有任何方法可以让 NHibernate 开箱即用。如果你想尝试,你可以伪造它,但它们似乎对我来说是平淡无奇的:
添加一个方法或属性,在幕后为这个架子返回一个 LINQ to NHibernate IQueryable:
public IQueryable<Book> FindBooks() {
return Resolver.Get<ISession>().Linq<Book>().Where(b => b.Shelf == this);
}
有人可能会这样消费的地方:
var shelf = ShelfRepo.Get(id);
var books = (from book shelf.FindBooks()
where book.Title == "The Great Gatsby"
select book);
呸!您正在通过您的域模型流血您的持久性需求!也许你可以通过让存储库发出 IQueryable 来让它变得更糟,它在运行时实际上是 LINQ to NHibernate:
public IQueryable<Book> FindBooks() {
return Resolver.Get<IRepository<Book>>().CreateQuery().Where(b => b.Shelf == this);
}
还是很乏味。
创建您自己的自定义集合类型(可能还有一个 IQueryable 实现)来包装实际书籍的私有(private)字段,并将 NHibernate 映射到该字段。然而,使用 ISession.CreateFilter 可能是一项艰巨的任务。您必须考虑“发现”当前 session ,将 LINQ 表达式转换为您可以在 CreateFilter 中使用的内容等。另外,您的业务逻辑仍然依赖于 NHibernate。
在这一点上没有什么能真正令人满意。在 NHibernate 可以为您对集合执行 LINQ 之前,看起来您最好只像已经建议的那样正常查询您的 Book 存储库,即使它看起来不那么性感或最佳。
关于c# - NHibernate IQueryable 集合作为根的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2774095/