簡體   English   中英

結合NHibernate中Query / QueryOver和DetachedCriteria的工作原理

[英]Combine workings of Query / QueryOver and DetachedCriteria in NHibernate

在我當前的項目中,我開始使用NHibernate,並且基本上一切運行良好,直到需要將某個實體的完整對象樹發送給我的服務使用者為止-急切地從服務器加載和發送的所有內容。

我希望我的查詢盡快。

搜索條件非常簡單:指定產品和指定部門的完整最新結果對象。

如果我這樣調用查詢,我將得到正確的結果:(但是這會產生3個查詢,至少,我得到了正確的結果)

Result res = session.QueryOver<Result>()
                 .Where(x => x.Product == product)
                 .Where(x => x.Department == department)
                 .OrderBy(x => x.Date).Desc
                 .Take(1).SingleOrDefault();

但是,並非所有子集合都急切地加載這樣的結果。 (是的,它仍然會創建3個查詢)。

因為我絕對需要在Content填充所有ResultContent類型的項目。 ResultContent有一些元素的集合,也有它們的集合。 我迫切需要所有這些集合完全填充所有子元素及其子元素的子元素,依此類推。

我現在幾乎整天都在處理NHibernate查詢,並且幾乎可以通過以下查詢實現正確的行為:

var resultCriteria = DetachedCriteria.For<Result>();
resultCriteria.SetFetchMode("Product", FetchMode.Eager);
resultCriteria.SetFetchMode("Department", FetchMode.Eager);
resultCriteria.SetFetchMode("Content", FetchMode.Join);
resultCriteria.SetFetchMode("Source", FetchMode.Join);
resultCriteria.SetFetchMode("Content.Numerics", FetchMode.Eager);
resultCriteria.SetFetchMode("Content.Numerics.DataCollection", FetchMode.Join);
resultCriteria.SetFetchMode("Content.Numerics.DataDescription", FetchMode.Join);
resultCriteria.SetFetchMode("Content.Numerics.DataDescription.DescriptionSource", FetchMode.Eager);
resultCriteria.SetMaxResults(5);
var relevantResults = resultCriteria.GetExecutableCriteria(session).List<Result>();

通過這種方法,我得到了5個結果,但是Content集合的填充沒有超出第一個元素。 對於以數字表示的DataCollection,僅查詢了5個元素,即使應該拉近500個項目也是如此。

我在FetchModes上玩了很多游戲,並且開始認為我將無法實現我將來所需要的東西。 您能否向我暗示正確的方向,我如何才能正確組合這兩種方法?

我是否應該使用HQL(我從未使用過,所以我想我會更加努力)?

注意:我在Google上搜索了很多,並嘗試了很多東西,但是就NHibernate和sql而言,我認為自己是一個菜鳥。 我將嘗試提高自己的技能,但時間壓力現在趨向於提出問題。

其他相關的類如下所示(這樣您就可以看到哪個類擁有什么的集合,當然也進行了很多簡化)

public class Result
{
    public virtual long Id { get; protected set; }
    public virtual Product Product { get; set; }
    public virtual Department Department { get; set; }
    public virtual DateTime Date { get; set; }
    public virtual ISet<ResultContent> Content { // getters and setters }
    public virtual ISet<ResultSource> Source { // getters and setters }
}

public class Product
{
    public virtual short Id { get; protected set; }
    public virtual string Name { get; set; }
    public virtual string Code { get; set; }
    public virtual string Description { get; set; }
}

public class Department
{
    public virtual short Id { get; protected set; }
    public virtual string Name { get; set; }
    public virtual string Code { get; set; }
    public virtual string Description { get; set; }
}

public class ResultContent
{
    public virtual Result Result { get; set; }
    public virtual Numerics Numerics { get; set; }
    public virtual long Revision { get; set; }
}

public class Numerics
{
    public virtual long Id { get; protected set; }
    public virtual string Name { get; set; }
    public virtual ISet<DataEntry> DataCollection { //getters and setters }
    public virtual ISet<DataDescription> DataDescription { //getters and setters}
}

DataEntry和DataDescription類僅包含Id,Date和字符串或布爾值。

嗨,你能嘗試一下嗎,

    Result ra = null;
    Product pa = null;
    Department da = null;
    Result res = session.QueryOver<Result>(() => ra)
        .JoinAlias(() => ra.Product ,() => pa)
        .JoinAlias(() => ra.Department ,() => da)
        .Where(() => pa  == product)
        .Where(() => da == department)
        .OrderBy(() => ra.Date).Desc
        .Take(1).SingleOrDefault();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM