.NET-es projekten vagyok épp. Ismeritek a SubSonic nevű csodát? Remek kis kódgenerátor, mert objektum-alapú DAL-t generál, ezáltal típusazonossági alapon kezelhetjük az adatbázis minden elemét (táblák, mezők, tárolj eljárások, view-k stb). Egészen egyszerű és érthető módon készíthetünk lekérdezéseket, beszúrásokat... szóval sokmindent, ami az alkalmazásunk adatszerkezetét biztosítja közte és az adatbázis-szerver között (MSSQL, SQLCE, Oracle, SQLite és MySQL - és állítólag hamarosan jön a PostgreSQL réteg is).
Na, de most nem a SubSonic csodáját szeretném ecsetelni, aki kíváncsi rá, annak szívesen mesélek róla más fórumon keresztül. A SubSonic bármilyen jó, tegnap egy hiányosságot tapasztaltam benne: lekérdezés készítésénél nem ad lehetőséget az asszociatív kezelésre (gy.k.: nem tudunk zárójelezni).
Az egyszerűsített módon definiálom a problémát: adott A, B és C feltétel a lekérdezésben. Ha azt akarom mondani, hogy azokat a rekordokat jelenítse meg, ahol A igaz ÉS B igaz ÉS C igaz, akkor semmi teendőm nincs. Csakhogy nekem arra volt szükségem, hogy A ÉS B VAGY C, de úgy, hogy ez valahogy így nézzen ki: A ÉS (B VAGY C), mivel ha nem zárójelezek, akkor a VAGY feltétel borít mindent, és visszad minden rekordot, ahol C teljesül.
Hogy miért?
Kevesen tudják vagy emlékeznek rá, hogy a logikai műveleteknek, mint matematikai műveleteknek van műveleti sorrendje. Vagy legalábbis elfelejtik, ahogyan most én is tettem.
Tehát ahogy az előbb említettem, zárójeles kifejezést nem adhatunk SubSonic-ban. A fentiek miatt ez pedig gond, mert nekem csoportosított értékre volt szükségem a B és C feltételt illetően.
Rémlett valami, amit tanultam még ezer évvel ezelőtt, de nem tudtam felidézni hirtelen, hogy mit. Egy kollégámnak felvetettem a fenti problémát, és ő kapásból mondta: De Morgan azonosságok.
BASSZUS! Tényleg! Persze már nem emlékeztem pontosan, de aztán gyorsan rájöttem, hogy bizony itt a logikai műveletek matematikai megfeleltetéséről van szó. Csak még mindig nem állt össze bennem a kép, és kolléga úr mondta (egyébként matematika-tanár szeretett volna lenni), hogy a De Morgan azonosságokkal a zárójelesen felírt műveletek felírhatóak zárójelek nélkül is a műveleti sorrendek betartásának megfelelően.
Na, itt már képbe kerültem. Tehát ha egy kifejezés értéke IGAZ, akkor az legyen 1, egyébként meg 0.
A következő táblázatban felírjuk, hogy A és B esetében milyen logikai eredmények szüketnek, a végére pedig odaírjuk, hogy matematikailag ez hogyan feleltethető meg szorzással és osztással (a teljesség igénye nélkül történik ez, ezért csak e két alapműveletet írom le):
A | B | A ÉS B | A VAGY B | A X B | A + B |
1 | 1 | 1 | 1 | 1 | 1 |
0 | 1 | 0 | 1 | 0 | 1 |
1 | 0 | 0 | 1 | 0 | 1 |
0 | 0 | 0 | 0 | 0 | 0 |
E táblázatból kitűnik, hogy a logikai ÉS megfelel a matematikai szorzásnak, illetve a VAGY művelet pedig az összeadásnak. Ez nekünk azért jó, mert így már felíhatjuk e műveletekkel a szükséges kifejezést:
A ÉS (B VAGY C) = A x (B + C)
Jó, nem? Bontsuk fel a zárójelet:
A x (B + C) = A x B + A x C
Nincs zárójel, a SubSonic esetében most már megoldottuk a problémát:
A x B + A x C = A ÉS B VAGY A ÉS C
tehát
A ÉS (B VAGY C) = A ÉS B VAGY A ÉS C
Ez pedig nem egyenlő A ÉS B VAGY C kifejezéssel, mivel matematikailag ez A x B + C. Csak egy szorzat hiányzik: C A-val történő felszorzása. :-)
Ezzel bebizonyítottuk, hogy a műveleti sorrend él a logikai műveletekre is, azaz ahogyan a matematikában a szorzás előrébb való, mint az összeadás, úgy a logikai műveletek esetében az ÉS operátor erősebb a VAGY operátornál, tehát először az ÉS értékelődik ki.
Néha rájön az ember, hogy nem volt hülyeség matematikát tanulni. Most kifejezetten örültem neki.