2012-07-12 62 views
3

」爲fully_qualified_type_name提取禁用懶惰特性,因爲它不支持實體級別的懶惰「。有誰知道爲什麼我從NHibernate/NH Profiler中獲得這個警告? 「

NH Profiler報告了此警告,因此我遇到了可怕的SELECT N + 1副作用。因此,如果返回2200個子組實體,則會執行額外的查詢來檢索每個InvoicePreference實體(總計2201個查詢)。有關這種關係的事情似乎是造成這個問題的原因。

以下是有問題的實體及其各自的映射。

實體1

public class Subgroup : Entity 
{ 
    public virtual string GroupNumber { get; set; } 

    public virtual string RUSNumber { get; set; } 

    public virtual string REANumber { get; set; } 

    public virtual string CustomerType { get; set; } 

    public virtual string Name { get; set; } 

    public virtual IList<IndividualEmployment> Employees { get; set; } 

    public virtual IList<BenefitsAdministrator> Administrators { get; set; } 

    public virtual InvoicePreference InvoicePreference { get; set; } 
} 

實體2

public class InvoicePreference : IEntity 
{ 
    public virtual Guid Id { get; set; } 

    public virtual Guid SubgroupId { get; set; } 

    public virtual bool PaperlessNotifications { get; set; } 
} 

映射1

public static AutoPersistenceModel ConfigureSubGroup(this AutoPersistenceModel 
autoPersistenceModel) 
{ 
    return autoPersistenceModel.Override<Subgroup>(map => 
    { 
     map.Table("SubgroupV"); 

     map.Id(s => s.Id).Column(SubGroupPrimaryKeyColumn); 

     map.Map(s => s.CustomerType, "BAS_Customer_Type"); 
     map.Map(s => s.RUSNumber, "BAS_RUS_Number"); 
     map.Map(s => s.GroupNumber, "BAS_Group_Number"); 
     map.Map(s => s.REANumber, "BAS_REA_Number"); 

     map.HasMany(s => s.Administrators).KeyColumn(SubGroupPrimaryKeyColumn); 
     map.HasMany(s => s.Employees).KeyColumn(SubGroupPrimaryKeyColumn); 
     map.HasOne(s => s.InvoicePreference).PropertyRef(i => i.SubgroupId); 
    }); 
} 

馬普ing 2

public static AutoPersistenceModel ConfigureInvoicePreference(this AutoPersistenceModel autoPersistenceModel) 
{ 
    return autoPersistenceModel.Override<InvoicePreference>(map => 
    { 
     map.Table("SubgroupInvoicePreference"); 
     map.Schema(RetirementStatementsSchemaName); 
    }); 
} 
+0

這是來自NH profiler的確切消息嗎? – 2012-07-13 06:41:15

+0

這不是確切的消息。它具有該類型的實際名稱。 WARN: 爲Neb.RetirementStatements.Services.Domain.Subgroup提取禁用惰性屬性,因爲它不支持在實體級懶惰 – 2012-07-13 14:46:09

+0

似乎與此問題有關。 http://stackoverflow.com/questions/4888140/fluent-nhibernate-references-and-propertyref-doing-a-select-with-lazy-load – 2012-07-13 15:03:37

回答

1

InvoicePreference被引用爲hasone。由於缺省情況下,NHibernate會創建一個代理來填充屬性InvoicePreference,並且要做到這一點,它需要InvoicePreference中不存在於Subgroup中的標識。因此它必須使用propertyref中的屬性來查詢它。

爲了彌補這方面做.Not.LazyLoad()和/或.Fetch.Join()

+0

我知道如何做到渴望加載和取得策略的細微差別,但我實際上不想對該房產/協會做任何事情。我沒有試圖加載它/訪問它。如果是這樣的話,那麼是的,我想要加載它。 – 2012-07-13 14:47:47

+0

我只是想知道爲什麼它特意試圖延遲加載這種關係。我沒有訪問該財產或任何其他人員,如員工和管理員。爲什麼它不會爲其他兩種關係做同樣的事情?它也應該嘗試延遲加載員工和管理員。其他2個是收款並且InvoicePreference不是?不應該「他們都表現出相同的方式不管?直到我訪問任何這些屬性,NHibernate不應該嘗試加載它們。 – 2012-07-13 14:59:27

+0

這是另一種說出你解釋的方式嗎? property-ref:延遲加載僅適用於對象ID。當通過目標實體中的不同列解決屬性關聯時,NH會熱切地獲取它。這並不是不可能的,它只是沒有實現:Bug – 2012-07-13 15:10:32

1

我想,有一些理由NH禁用延遲加載「在實體層面」,我的理解是不建立代理。這可能有幾個原因。你之前收到過另一個警告嗎?我不明白爲什麼它禁用了「懶惰的特性」,這意味着一些屬性被延遲加載。這是一個明確用於映射的功能,但在映射定義中我看不到這樣的內容。

要克服N + 1,您可以使用Fetch.Join。我對此有不好的經驗,因爲查詢變得非常大。在複雜模型中,您可能會遇到一些數據庫服務器限制(如查詢的最大列數)。最好是使用批量大小,這顯着減少了查詢次數。看看my answer到「Nhinerbate lazy loading of reference entity」。

+0

其實我不希望它做急切的加載。我不希望實體加載,因爲我沒有使用它的請求。我甚至沒有觸及那個財產。我當然使用AutoMapper,但據我所知,它並沒有觸及該屬性,因爲它沒有被用於正在執行的映射中。 – 2012-07-13 14:44:49

+0

如果你不想急於加載,請不要關閉它。不要執行Fetch.Join並使用批量大小。我不知道你爲什麼得到這個警告。你可以在NH profiler論壇/支持網站上詢問。 – 2012-07-16 05:44:28

+0

會考慮。謝謝Stefan。 – 2012-07-16 18:08:38

相關問題