NHibernate 3 LINQ:如何过滤 IQueryable 以仅选择 T 类及其子类的对象?
Posted
技术标签:
【中文标题】NHibernate 3 LINQ:如何过滤 IQueryable 以仅选择 T 类及其子类的对象?【英文标题】:NHibernate 3 LINQ : How to filter IQueryable to select only objects of class T and its subclasses? 【发布时间】:2011-01-02 15:42:34 【问题描述】:我想升级我的应用程序以使用 NHiberante 3 而不是 NHibernate 2.1.2,但在使用新的 LINQ 提供程序时遇到了一些问题。这个问题是关于其中之一的。假设我有以下类层次结构:
public abstract class PageData
public int ID get; set;
public string Title get; set;
public class ArticlePageData : PageData
public DateTime PublishedDate get; set;
public string Body get; set;
public class ExtendedArticlePageData : ArticlePageData
public string Preamble get; set;
我使用 Fluent NHibernate 将这些类映射到数据库:
public class PageDataMap : ClassMap<PageData>
public PageDataMap()
Table("PageData");
Id(x => x.ID);
Map(x => x.Title);
DiscriminateSubClassesOnColumn("PageType");
public class ArticlePageDataMap : SubclassMap<ArticlePageData>
public ArticlePageDataMap()
Join("ArticlePageData", p =>
p.KeyColumn("ID");
p.Map(x => x.PublishedDate);
p.Map(x => x.Body);
);
public class ExtendedArticlePageDataMap : SubclassMap<ExtendedArticlePageData>
public ExtendedArticlePageDataMap ()
Join("ExtendedArticlePageData", p =>
p.KeyColumn("ID");
p.Map(x => x.Preamble);
);
然后我想查询所有页面并进行一些过滤:
IQueryable<PageData> pages = session.Query<PageData>();
...
var articles = pages.OfType<ArticlePageData>().Where(x => x.PublishedDate >= (DateTime.Now - TimeSpan.FromDays(7))).ToList();
在这种情况下,NHibernate 3.0.0 失败并出现 NotSupported 异常,但在 NH 的开发版本中有错误修复 NH-2375 导致此代码工作。但是,不幸的是,OfType() 方法按确切类型过滤对象,并且只选择 ArticlePageData 类的对象。旧的 Linq to NH 提供程序在相同的情况下选择 ArticlePageData 和 ExtendedArticlePageData。 如何使用新的 Linq to NH 提供程序进行此类过滤(仅选择 T 类及其子类的对象)?
【问题讨论】:
您拥有哪个版本的 Linq 提供程序?我下载了 NH3.0 (NHibernate-3.0.0.GA-bin) 但似乎找不到比 2.1.2 版本更新的提供程序。谢谢。 自 3.0.0 版以来,linq 提供程序是 NHibernate 的一部分。除了 NHibernate 本身,您不需要下载其他任何东西。所有 linq 的东西都在 NHibernate.Linq 命名空间中。 【参考方案1】:session.Query<T>().OfType<SubT>()
没有什么意义,它不会让你过滤子类的属性。请改用session.Query<SubT>()
。
【讨论】:
当然,但是如果没有对我的应用程序进行大量更改,我就无法使用 QueryBlogs.Where(b => b.Pages.OfType<ArticlePageData>().Any(p => p.PublishedDate >= DateTime.Now))
【参考方案2】:
你可以使用
var article = pages.AsEnumerable().OfType().Where(x => x.PublishedDate >= (DateTime.Now - TimeSpan.FromDays(7))).ToList();等待 NHibernate 3.0.1。 或者你可以使用
session.Query()而不是
session.Query【讨论】:
第一个想法很糟糕:它将所有内容加载到内存中。 当然,我可以进行内存过滤,但在性能方面这是个坏主意。 OfType以上是关于NHibernate 3 LINQ:如何过滤 IQueryable 以仅选择 T 类及其子类的对象?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 LINQ 在 NHibernate 3 中实现关键字搜索?
使用 NHibernate 3.0 QueryOver 或 LINQ 提供程序的权衡
在 NHibernate 3.0 Linq 中急切加载多个兄弟姐妹和孙辈(堂兄弟?)的良好行为