2009-11-09 14 views
6

İki ilişkili iş nesnesine sahibim - A ve B. dernek (A-> B) çok-bir, B.Id ile A'da yabancı anahtar (A'da DB'de A.B_id var).NHibernate - tüm nesneyi tembel yüklemeden ilişkili bir nesnenin kimliğine erişin

lazy = true kullanıyorum ve problemlerimin çoğunu çözdüm, ancak A ToString'de DB'ye daha fazla yolculuk yapmadan da olması gereken A.B.Id'yi yazdırmak istiyorum. ancak A.B'ye erişmek proxy'yi etkinleştirir ve bu açık bir oturum bağlamında olmadığından bir istisna atar. Kolay ve çirkin bir çözüm, A.B_id özelliğine sahip olmak olabilir.

ama bu, ilk etapta kaçınmaya çalıştığımız şeylerin bir parçası. Bunu yapmak için herhangi bir "organik" yol? :) teşekkürler!


GÜNCELLEME: yalnızca önbelleğe alma ve Session.Get vs. Session.Load hakkında bilgi edinin. Nesne yoksa (Session.Load) ve diğeri boş nesneyi (Session.Get) döndürürse, yalnızca bir istisna atar. here'u önbelleğe alma hakkında okuduktan sonra, Session.Load nesnesine bir proxy döndürdüğü ve kimliğinden başka bir özelliğe eriştiğinde yalnızca tembel bir şekilde getirildiği açıktır; Şimdilik ayrı nesne kimliklerini ekledim (B_Id ekledim, böylece ABId'yi kullanarak A.B_Id olarak erişebildim)

+0

Bunu neden yapmak istiyorsunuz? – Paco

+0

dediğim gibi, sadece günlük yazdırma vb. Için, A ToString() içinde. Sadece ID'den başka alanlara ihtiyacım yok. –

cevap

3

Aynı sebepten ötürü birçok benim için açık AB-ID özelliklerini kullandım -bir-bir ilişki. Bunu, bu soruna bir çözüm sağladığı için hızlı ve kirli bir çözüm olarak görmüyorum ve aynı zamanda esneklik çok tasarruf alanıdır, yani B nesnesini yalnızca A'ya atamak için veritabanından almam gerekmez Bir sorgu dizesinde veya başka bir yerde B_ID'ye sahip olduğumda ilişkilendirmeyi oluşturmak için.

Benim eşleme dosyaları useually şu şekilde görünür:

<property name="CreatorID" column="CreatorID" type="Int32" not-null="true" /> 
<many-to-one name="Creator" column="CreatorID" class="SystemUser" insert="false" update="false" cascade="none" /> 

size 2 özelliklerden birini görebileceğiniz gibi NHibernate ekler veya updatas olan veritabanına 2 kez bu sütun gönderme zorunda kalmamak için salt okunur olması gerekir olay. Yukarıdakiler salt okunur olarak yazılır (insert = "false" update = "false" niteliklerini kullanarak), bire-bir yapar, ancak isterseniz yalnızca CreatorID özelliğini okuyabilirsiniz.

Sadece bire bir olmak üzere, varlık sınıfı A'nızda B.ID değerini tutmak için bir özelliğiniz yok. Bunu elde etmenin tek yolu, proxy'yi tetikleyen B nesnesine erişmektir ve veritabanına bir sorgulama yapar (eğer zaten oturumda yüklü değilse).

Bir çözüm sunan ve aynı esnekliği sunan başka bir seçeneği duymaktan memnuniyet duyarız.

using NHibernate.Proxy; 
... 
object id = null; 
if (obj.IsProxy()) // obj is the object you want to get its identifier. 
{ 
    var proxy = obj as INHibernateProxy; 
    if (proxy != null) 
    { 
     var li = proxy.HibernateLazyInitializer; 
     if (li != null) 
      id = li.Identifier; 
    } 
} 
+0

Yine de bunun ABId kullanılarak yapılmasını istiyorum - Yinelenen verileri beğenmedim - Bu özelliklere sahiptim ve * çıkardım * Onları daha fazla araştıracağım ama şimdilik bunu yapacağım . Teşekkürler! –

+0

@YonatanKarni Tamamen katılıyorum. Bununla birlikte büyük bir performans sorunu var. Bir varlık koleksiyonuna çok sayıda (nxy) varlık ekle (set destekli) ve n '' n '', proxy başına bir tane seçtiği gibi performansı öldürür, 'set.Add' yaptığı gibi sırayla gerçekleştirilir. şey. – jasper

5

, tüm nesne yüklemek için veritabanına başka gidiş dönüş olmadan ilişkili nesnenin kimliği almak için aşağıdaki kodu kullanabilirsiniz Nhibernate oturumu:

session.GetIdentifier(obj); 
1

Sen GetIdentifier yöntemi kullanabilirsiniz: Eğer NHibernate 3.2 veya üstü kullanıyorsanız

İlgili konular