我有這樣的NHibernate的模型:NHibernate的 - 獲取引用的列值
public class RootTable
{
public virtual string Name { get; set; }
public virtual string Description { get; set; }
public virtual DateTime? Start { get; set; }
public virtual DateTime? Finish { get; set; }
public virtual IList<Leaf1> ChildCollection1 { get; set; }
}
public class Leaf1
{
public virtual int ID { get; set; }
public virtual string Info1 { get; set; }
public virtual string Info2 { get; set; }
public virtual RootTable Parent { get; set; }
}
public class RootMapping : ClassMap<RootTable>
{
public RootMapping()
{
Table("RootTable");
Id(c => c.Name);
Map(c => c.Description, "Desc").Length(20);
Map(c => c.Start).Length(20);
Map(c => c.Finish).Length(20);
HasMany(c => c.ChildCollection1)
.Cascade.All()
.LazyLoad()
.Inverse();
}
}
public class Leaf1Mapping : ClassMap<Leaf1>
{
public Leaf1Mapping()
{
Table("LeafTable1");
Id(c => c.ID, "RowID").GeneratedBy.Identity();
Map(c => c.Info1).Length(20);
Map(c => c.Info2).Length(20);
References(c => c.Parent).Column("Parent").LazyLoad();
}
}
我試圖做的是無惰性加載RootTable訪問Leaf1引用的列的值。
。換句話說,我有這樣的:
this.LogMessage("Loading leaves...");
var allleafs = session.CreateCriteria(typeof(Leaf1)).List<Leaf1>();
this.LogMessage("Loaded leaves...");
var leaf = allleafs[0];
this.LogMessage("Leaf metadata:");
// This causes a lazy-load of the RootTable object.
this.LogMessage("Leaf parent is " + leaf.Parent);
現在我真正想要的是值「父」,因爲它是存儲在底層數據庫的 - 我不在乎父對象,我不想加載它,我只想要獲得原始值。我不能訪問包含該值的字段(即leaf.Parent.Name
),我想這在一個通用的方式工作...
[背景] 終究是堵到使用的審計框架NHibernate攔截器,所以這需要以通用的方式工作,以便任何傳入的對象都可以報告更改後的值。這是完全可能的,子節點將不會改變根節點,所以當調用攔截器的OnFlushDirty()
時,我做而不是希望攔截器導致其他對象的延遲加載。
我知道我可以直接引用父屬性(例如,我可以說「leaf.Parent.Name」),這將得到我的價值沒有惰性負載,但似乎並沒有一個快速的方法以確定「名稱」是我想要返回的關鍵屬性。
[編輯補充...]
走在樹似乎並沒有因爲我得到一個空引用異常工作:
var theType = leaf.Parent.GetType();
// This line returns a NULL due to the proxy class.
var metadata = factory.GetClassMetadata(theType);
var idProp = metadata.IdentifierPropertyName;
var prop = theType.GetProperty(idProp);
var val = prop.GetValue(leaf.Parent, null);
this.LogMessage("Leaf parent is " + val);
現在,theType回來爲RootTableProxy
,所以是隻是一個佔位符,因爲主類沒有加載。這意味着metadata
爲空,因爲沒有類別元數據,因此idProp
失敗並出現空引用異常。
所以我實際上看不到如何在沒有延遲加載的情況下獲得引用的列值:肯定這是不對的?
編輯追加(更多!)
我想到了一個簡單的解決方案已被發現使用session.GetIdentifier()。然而,這似乎並不適用於所有情況:在攔截器中調用session.GetIdentifier(state[i])
對某些對象造成異常,指出該對象不屬於當前會話的一部分,因此仍在尋找一種更可靠的解決方案,而不會訴諸於反射。任何想法歡迎...
這是一個想法 - 我們有一個大的領域模型,所以需要通過代碼添加這個屬性很大的步行。我們也許可以通過僅僅在那些需要它的屬性上進行限制 - 將仔細研究。雖然對於我認爲NH應該免費贈送給我的東西,似乎還是有些冒失......好吧。 –