4

I want to upgrade my application to use NHiberante 3 instead of NHibernate 2.1.2 but faced some problems with the new LINQ provider. This question is about one of them. Assume that I have a following hierarchy of classes:

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; }
}

I use Fluent NHibernate to map these classes to the database:

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);
            });
        }
}

And then I want to query all pages and do some filtering:

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 fails with the NotSupported exception in this case, but there is bugfix NH-2375 in the developing version of NH which leads this code to work. But, unfortunately, OfType() method filters the objects by exact type and only selects objects of ArticlePageData class. The old Linq to NH provider selects ArticlePageData and ExtendedArticlePageData in the same case. How can I do such filtering (select only objects of class T and its subclasses) with the new Linq to NH provider?

UpTheCreek
  • 31,444
  • 34
  • 152
  • 221
  • Which version of the Linq provider do you have? I donwloaded NH3.0 (NHibernate-3.0.0.GA-bin) but can't seem to find a newer provider than the 2.1.2 version. Thanks. – alphadogg Jan 05 '11 at 00:34
  • Since version 3.0.0 linq provider is a part of NHibernate. You don't need to download anything else except NHibernate itself. All the linq stuff is in NHibernate.Linq namespace. – Anton Nikolayev Jan 05 '11 at 08:01

2 Answers2

2

session.Query<T>().OfType<SubT>() makes little sense, and it won't let you filter on properties of the subclass. Use session.Query<SubT>() instead.

Diego Mijelshon
  • 52,548
  • 16
  • 116
  • 154
  • 1
    Sure, but I can't use Query without a big bunch of changes in my application, that's why I asked this question. I wonder if some way to do OfType() filtering with the existing IQueryable exists. – Anton Nikolayev Jan 02 '11 at 23:44
  • You'll have to do the changes, because it's not possible. – Diego Mijelshon Jan 02 '11 at 23:49
  • @DiegoMijelshon Is there a bug describing this issue? – AlexDev Jul 16 '15 at 20:41
  • @alexdev that is not a bug – Diego Mijelshon Jul 16 '15 at 21:33
  • I mean feature. Do you know if there is a Jira issue for this? I would like to contribute. Even though there is a workaround for this case it is a problem when filtering inside collections. i.e. `Blogs.Where(b => b.Pages.OfType().Any(p => p.PublishedDate >= DateTime.Now))` – AlexDev Jul 17 '15 at 10:36
0

You can use

var articles = pages.AsEnumerable().OfType<ArticlePageData>().Where(x => x.PublishedDate >= (DateTime.Now - TimeSpan.FromDays(7))).ToList();

and wait for NHibernate 3.0.1. or maybe you can use

session.Query<ArticlePageData>()

instead of

session.Query<PageData>()
Sławomir Rosiek
  • 4,038
  • 3
  • 25
  • 43