Hüseyin Çelik Blog Sayfasi

.Net, Java, Android, Progress 4gl Paylasimlarim

XPO (eXpressPersistent Objects) LEFT OUTER JOIN INNER JOIN kullanimi

Merhaba arkadaslar XPO ile ilgili güzel bir soru geldi. Bende bu sorunun cevabini sizlerle paylasmak istedim.

Soru su;

XPO da left ve inner join nasil oluyor?

XPO ile ilk tanistigimda left join benim içinde büyük bir problemdi. Bunu çözemedigim için sorgularimizdan View yaziyor ve bu view leri XPO tarafinda XPLiteObject ile kullaniyorduk. Tabi dogru yöntem bu degildi. XPO için XPLiteObject de bir DB tablosuydu.

Sonunda join problemini çözdük. Öncelikle inner join yapabilmek için iki tablonun XPO ya iliskili oldugunun söylenmesi (tanitilmasi) gerekiyor. Tabi bu bilgileri XPO ve XAF ye nitelik yani attribute ile söylüyoruz(tanitiyoruz). Iki tabloyu join ile sorgulayabilmek için Association attribute kullanilarak iliskilendirilmesi gerekiyor.

Örnek bir obje:

[Persistent("T_Ogrenciler")]
[OptimisticLocking(false)]
[DeferredDeletion(false)]
public partial class Ogrenci
{
    public Ogrenci() { }
    public Ogrenci(Session session) : base(session) { }

    [Size(100)]
    [RuleRequiredField("Ogrenci Adi Zorunludur!", DefaultContexts.Save)]
    public string OgrenciAdi { get; set; }

    [Size(100)]
    public string OgrenciSoyadi { get; set; }

    [Size(15)]
    public string Telefon1 { get; set; }

    [Size(15)]
    public string Telefon2 { get; set; }

    [Size(SizeAttribute.Unlimited)]
    public string Adres { get; set; }

    [Association("Belgeler.Ogrenciler", typeof(Belgeler)), DevExpress.Xpo.Aggregated, XafDisplayName("Belgeler")]
    public XPCollection Belgeler
    {
        get { return GetCollection("Belgeler"); }
    }
}

Belge objesi:

[Persistent("T_Belgeler")]
[OptimisticLocking(false)]
[DeferredDeletion(false)]
public partial class Belgeler
{
    public Belgeler() { }
    public Belgeler(Session session) : base(session) { }

    [Size(250)]
    [RuleRequiredField("Belge Ad bilgisi zorunludur!", DefaultContexts.Save)]
    public string Ad { get; set; }

    [Size(400)]
    public string DosyaAdi { get; set; }

    [Size(50)]
    public string Uzanti { get; set; }

    public long Boyut { get; set; }

    #region Dosya
    private FileData fDosya;
    [XmlIgnore]
    //[FileTypeFilter("Resim Dosyasi (*.jpg)", 1, "*.jpg")]
    //[FileTypeFilter("Resim Dosyasi (*.jpeg)", 2, "*.Jpeg", "*.jpeg")]
    //[FileTypeFilter("Tum Dosyasi (*.*)", 3, "*.*")]
    [ExpandObjectMembers(ExpandObjectMembers.Never), VisibleInListView(false), VisibleInLookupListView(false)]
    public FileData Dosya
    {
        get { return fDosya; }
        set
        {
            SetPropertyValue<FileData>("Dosya", ref fDosya, value);
        }
    }
    #endregion

    [Association("Belgeler.Ogrenciler")]
    public Ogrenci Ogrenci { get; set; }

}

Bu objeleri kullanarak basit bir select çekelim.

var rows = (from x in new XPQuery<Belgeler>(XpoDefault.Session)
                        where x.Ogrenci.OgrenciAdi == "ddddd"
                        select x).ToList();

Bu selecti XPO nasil anladigini ve nasil yorumladigini görelim.

select N0.[OID],N0.[Aciklama],N0.[Aciklama2],N0.[OlusturanKullanici],N0.[OlusturmaTarihi],N0.[GüncelleyenKullanici],N0.[GuncellemeTarihi],N0.[Durum],N0.[Ad],N0.[DosyaAdi],N0.[Uzanti],N0.[Boyut],N0.[Dosya],N0.[Ogrenci] from ([T_Belgeler] N0  inner join [T_Ogrenciler] N1 on (N0.[Ogrenci] = N1.[OID])) where (N1.[OgrenciAdi] = 'ddddd')

Gördügünüz gibi burada olusan SQL inner join olarak olusturuldu. Simdi bu sql left join olarak nasil hazirlariz?

var rows = (from o in new XPQuery<Ogrenci>(XpoDefault.Session)
                        join b in new XPQuery<Belgeler>(XpoDefault.Session)
                        on o equals b.Ogrenci
                        where b != null
                        select new { o.OgrenciAdi, b.Ad }).ToList();

XPO bu kodu nasil yorumlamis onu görelim.

select N0.[OgrenciAdi],N1.[Ad] from ([T_Ogrenciler] N0  left join [T_Belgeler] N1 on (N0.[OID] = N1.[Ogrenci])) where not (N1.[OID] is null)

Evet, gördügünüz gibi left join olarak hazirladi.

Assocation, XPO için iliski tanimlama attiributedür. XPO iliskili bir yapi destekler. Aslinda ögrenci ve Belge iliskidir. Ancak siz bunu veritabani seviyesinde iliskili tutmak istemeyebilirsiniz. XPO burda size NoForeignKey attribute ünü kullaniminiza sunmustur. Bu attribute sadece XPO tabloyu olustururken yada alter ederken iki tablo arasindaki iliskiyi tanimlamaz. Bu attribute kullanmadan olusturulan association propertiler veri tabaninda foreign key olarak tanimlanir. Bu attribute kullanirsaniz foreign key olarak tanimlanmaz. Son olarak assocation attribute ile birlikte kullanilan aggregated deyimi vardir. Bu deyim SQL veri tabaninda foreign key tanimlanirken update delete cascade özelligi vardir. Buda ona benzer. Yani üst tablo silindiginde detay tablonunda silinmesini isterseniz bunu kullanabilirsiniz. SQL veri tabaninda da ayni mantik vardir.

Umarim faydali olmustur.

 

Loading