2010-07-09 15 views
14

PHP için Doctrine ORM (v1.2) ile deneme yapıyorum. İki çocuk sınıfı "cin" ve "viski" ile bir sınıf "likör" tanımladım. Sınıfları üç ayrı veritabanı tablosuna ayırmak için somut kalıtım (çoğu literatürde sınıf tablosu kalıtım) kullanıyorum. PHP doctrine 1.2 ORM - sınıf tablosu devri ile polimorfik sorgular

aşağıdaki yürütmek çalışılıyor:

$liquor_table = Doctrine_Core::getTable('liquor'); 
$liquors = $liquor_table->findAll(); 

Başlangıçta, onlar viski veya cin olsun, $ likörler tüm likör içeren bir Doctrine_Collection olması bekleniyor. Ama kodu çalıştırdığımda, viski ve cin veritabanı tablolarında birkaç satır olmasına rağmen boş bir koleksiyon alacağım. Oluşturulan SQL'e dayanarak nedenini anlıyorum: ORM, gerçek verilerin depolandığı viski/gin tablolarını değil, "likör" tablosunu sorgulamaktadır.

Devralma türünü sütun birleştirmeye (basit tablo devralma) geçirdiğimde, kodun mükemmel çalıştığını unutmayın.

Tüm sıvıları içeren bir Doctrine_Collection elde etmenin en iyi yolu nedir? Ben Doktrini "viski" ve "cin" tablolardan sonuç kümelerini birleştirmek için perde arkasında SQL UNION işlem gerçekleştirme bekliyorum gibi

biraz daha araştırmadan sonra

Güncelleme görünüyor.

Bu, polimorfik sorgu olarak bilinir.

this ticket'a göre, bu işlev Doctrine 1.x'te bulunmamaktadır. 2.0 sürümü için hedeflenmiştir. (Ayrıca CTI için Doctrine 2.0 belgelerine bakın). Bu bilginin ışığında, bu eksikliği gidermek için en temiz ve en verimli yol ne olurdu? Tek tablo devralmaya geçilsin mi? İki DQL sorgusu gerçekleştirin ve elde edilen Doctrine_Collections öğesini manuel olarak birleştirin mi?

cevap

3

Diğerlerini farklı projelerde denedim. Column_aggregation ile polimorfik sorguları taklit edebilirsiniz. Genel olarak kalıtım, Doktrin (1.x) 'de biraz buggy olan bir şeydir. 2.x ile bu değişecek, bu yüzden gelecekte daha iyi seçeneklere sahip olabiliriz.

0

Bir süredir aradığınızı tam olarak yapacak bir ORM'nin (üretime hazır değil) başlangıçlarını yazdım. Sadece bir kavram kanıtı alabilmem için. Tüm çalışmalarım bir şekilde kod ve verileri karıştırdığınızı gösterdi (likör tablosundaki alt sınıf bilgileri).

Yapabilecekleriniz, kendi sınıf tablosunu sorgulayan, kendi sınıfınızdaki bir soruyu yazmaktır. İçindeki sınıfındaki tüm alt sınıfların sabit koduna sahip olmayan ile kurtulmanın en iyi yolu, içindeki alt sınıfın sınıf adını içeren bir sütuna sahip olmaktır.

Ayrıntıları yaymak tamamen size kalmış. En normalize (ve eğer burada yanılıyorsam beni düzeltebilir) bence bunu yapmak, içki sınıfınızda görünen tüm alanları likör masasında saklamak. Daha sonra, her bir alt sınıf için, alt sınıf türüne ait spesifik verileri saklayan bir tabloya sahip olun. Kodunuz, birleştirme gerçekleştirmek için alt sınıfın adını almak için likör tablosunu okuduğu için kod ve verileri karıştırdığınız noktadır.

Ben arabalar & bisiklet ve benim örneğin aralarında bazı minimal, ama önemsiz farklılıklar kullanacağız:

Ride 
---- 
id 
name 
type 

(1, 'Sebring', 'Car') 
(2, 'My Bike', 'Bicycle') 

Bicycle 
------- 
id 
bike_chain_length 

(2, '2 feet') 

Car 
--- 
id 
engine_size 

(1, '6 cylinders') 

alt sınıf tablosundaki tüm likör sınıf verileri depolamak gibi öne buradan varyasyonları her türlü var ve sadece likör tablosundaki referansları ve alt sınıfı isimlerini saklamak. En azından bunu beğendim çünkü ortak verileri topluyorsanız, ortak alanlar için her bir alt sınıf tablosunu sorgulamanızdan tasarruf etmenizi sağlar.

Bu yardımcı olur umarız! Şu an için Doktrinin tek istikrarlı ve kullanışlı mirasçı modu, column_aggregation şeklindedir: