Kirjautuminen

Haku

Tehtävät

Keskustelu: Projektit: .NET/MySql Orm

runeberg [21.02.2014 20:25:56]

#

Otsikko on liian mahtipontinen, mutta en parempaakaan termiä keksinyt, ja Orm toimii myös työnimenä.

Yhteen omaan projektiini tarvitsin ominaisuuden, millä voisin luoda olioita ja tallentaa sekä hakea niitä MySql tietokannasta ilman ylimääräisiä kikkailuja. Ajatukseni oli tehdä kaikesta mahdollisimman automaattista, eli ei tarvitsisi huolehtia/tietää tietokannasta tiettyjä välttämättömyyksiä enempää.
Reilut 5 vuotta käyttäneeni kaupallista DevExpress Xpo:ta, totuin sen ylivertaisuuteen ja liian pitkään jatkuneena harrastelija vuosinani jäin kaipaan sen ominaisuuksia yhdistettynä edulliseen/ilmaiseen MySql tietokantaan, sillä MsSql "hotellit" on liian kalliita, kuten myös lisenssi ko. kirjastoon.

Projektini käyttää MySql Connector/Net kirjastoa ja projektini on kirjoitettu C# kielellä.

Jotta kaikille avautuisi, mitä haen, hieman koodia.

Luokan / taulun muodostus

public class User : RunebergObject
{
  public User()
  {
    base.MemberInstance = this;
  }
  // normi kauraa
  public string Name;
  public string Login;
  public string Password;
  public int Role;
}

RunebergObject pitää sisällään Id arvon, mikä vastaa tietokannan foreing key:tä, jolloin voit luoda olion id arvon perusteella:

User user = new User();
user.Find(1);

Jolloin voi käyttää:

Console.WriteLine(user.Name);

Jos haluaa ladata koko taulun, niin:

RunebergObjectCollection<User> users = new RunebergObjectCollection<User>();
users.GetAll();

Tai tietyllä ehdolla:

RunebergObjectCollection<User> users= new RunebergObjectCollection<User>();
users.GetCollection("Role=1");

Listaa voi myös käyttää oliossa:

public class User : RunebergObject
{
  public User()
  {
    base.MemberInstance = this;
  }
  // normi kauraa
  public string Name;
  public string Login;
  public string Password;
  public int Role;
  public RunebergObjectCollection<Message> Messages
  {
    get
    {
      RunebergObjectCollection<Message> messages = new RunebergObjectCollection<Message>();
      messages.GetCollection("User="+this.Id);
      return messages;
    }
  }
}

Jolloin voidaan tehdä:

User user = new User();
user.Find(1);
if(user.Id > 0) // tarkistus, runerberg olion luonnissa olion id on -1
{
  dataGrid.ItemSource = user.Messages;
}

Myös viittaus toiseen olioon toimii, siitä myö luodaan instanssi tarvittaessa (siitä lisää myöhemmin)

public class User : RunebergObject
{
  public User()
  {
    base.MemberInstance = this;
  }
  // normi kauraa
  public string Name;
  ...
  public Message Message;
}

// käytetään user.Message.vaikkaMessage;

Tietusti metodit Save() ja Delete() on käytössä.
Eli lopputuloksena, mitä halusin, on että voit luoda normaalisti luokan, jossa on muuttujia, ominaisuuksia yms. joiden arvot voidaan tallentaa kantaan pelkästään perimällä RunerbergObject luokan ja ilmoittaa sille rakentajassa kuka olet.

Tämä tosiaan luotu omaa projektia varten mahdollisimman nopeasti. Alunperinkään ei ollut tarkoitus tästä mitään tietoa julkaista, mutta mieleen tuli ajatus, jos tästä voisi myös jollekkin muulle olla käyttöä.
Mikäli mielenkiintoa löytyy, on seuraavia tavoitteita, ennenkuin voi julkaista:

- Siisitä sorsat
- Kommentointi
- Virheenkäsittely (Omassa projektissani toimii, kun tiedän miten käyttää)
- Asetuksia/vaihtoehtoja (kovakoodaus pois)
- Vaihtoehtoja, miten käsittelee viittuksia toisiin luokkiin (kts. yllä)

Muuta miinusta: Luokan muuttujien on oltava case sensitive tietokannan columnien kanssa, kuten luokan nimenkin. Myöskään JOIN yms. kikkailut ei toimi, eli jos luokassa User on viittaus luokkaan Message, niin taulussa User on oltava kenttä Message jonka tyypi on int, joka sisältää id:n vastaavaan Messageen.

Tulevaa:
Parannella juurikin edellä mainittuja asioita, myöskin se, että ei tarvitsisi pitää tietokannasta huolta, vaan jos luot uusia tauluja tai kenttiä, niin tallentaessa osattaisiin luoda puuttuvat.

Hieman sekava alotus, mutta kysykää, mikäli koko homman idea jäi roikkumaan.

feenix [22.02.2014 10:34:11]

#

Eikö ehdot teksteinä ole huiman vanhanaikaista ja vieläpä riski? Kuitenkin on olemassa LINQ, parametrisoidut kyselyt jne. Samoin itselleni on outoa, että ensin luodaan olio, sitten pyydetään olioon sisältö ja vielä sen jälkeen pitää tarkistaa onnistuiko se. Miksei Find() suoraan sano, onnistuiko? Miksei mieluummin staattinen metodi, joka joko palauttaa olion tai nullin, jos sisältöä ei löydy? Pitääkö tuo varmasti huolen, että joka kerta pyydettäessä oliota tulee sama olio, eli tietoja ei katoa?

Ja sitten aina tulee se "mitä eroa ja hyötyä tästä on jo olemassaoleviin, hyvin toimiviin järjestelmiin?" mieleen, koska itse toki en ikinä ole keksinyt pyörää uudelleen... O:)

runeberg [22.02.2014 22:42:01]

#

Tämä tosiaan kiireessä omiin tarpesiin luotu, eikä mikään ole täysin loppuum asti mietitty. Tarkoitus parannella sitä mukaan, kun omia tarpeita ilmenee.

Vielä tuosta pyörän keksimisestä uudelleen, niin itse en ole löytänyt vapaata kirjastoa, jolla käsitellä näitä asioita MySql:n kanssa. Toki .Net tarjoaa valmiit komponentit MsSql:n kanssa toimimiseen, jolloin voisi myös käyttää LINQua

feenix kirjoitti:

Samoin itselleni on outoa, että ensin luodaan olio, sitten pyydetään olioon sisältö ja vielä sen jälkeen pitää tarkistaa onnistuiko se. Miksei Find() suoraan sano, onnistuiko?

Tämä oli ratkasu sen takia, että ei tehdä turhaan tietokanta kyselyitä. Tarkoitus onkin lisätä ominaisuus, että voisin olion luonnin yhteydessä lisätä viittauksen, mikäli haluan luoda olion tietokannan arvoilla, tai puhtaan uuden olion, jonka tallennan myöhemmin.

Grez [23.02.2014 06:49:49]

#

runeberg kirjoitti:

Vielä tuosta pyörän keksimisestä uudelleen, niin itse en ole löytänyt vapaata kirjastoa, jolla käsitellä näitä asioita MySql:n kanssa.

Eikös Entity Framework ole Apache 2.0 lisenssillä. Tosin MySQL:n kanssa ei toimi ihan kaikki hienoudet mitkä toimii MSSQL:n kanssa, mutta uskoisin kuitenkin että kaikki sellaiset jutut ja enemmänkin toimii mitkä tuossa omassa kirjastossasi.

runeberg [15.03.2014 14:07:33]

#

Vaikuttaisi siltä, että Visual Studion Express versioon ei saa liitettyä noita mysql connectoria ja mysql for visual studio (tms.) liitännäisiä, jotka ovat olennaisia entity fw sujuvaan käyttöön mysql:n kanssa. Voin toki olla väärässäkin, mutta omilla yrityksilläni se ei onnistunut ja myös jossain netin syövereissä olevissa jutuissa puhuttiin samaa.

Lisäksi entity fw:n kannsa on "ylimääräisiä" kikkailuja, kuten viittauksessa toiseen luokkaan täytyy luokan sisältää ylimääräinen property, MyClassId, luokkaan viittauksen lisäksi. Omassa "kirjastossani" riittää pelkkä viittaus. Mutta perehdyttyäni nyt tarkemmin Entity frameworkiin, löysin sieltä muutaman kiinnostavan jutun, mitä voisin lisätä omaani, esim. lazy loadingin sujuvampi käyttö. Entityssä lazy loadingin kanssa joutuu kirjoittamaan ylimääräisen luokan / controllerin. Nyt omassani ei tätä tarvitse tehdä. Tosin tietyissä tilanteissa ongelmia tulee pinon ylivuodon kanssa, mutta omassa projektissani osaan kiertää sen :)

Grez kirjoitti:

uskoisin kuitenkin että kaikki sellaiset jutut ja enemmänkin toimii mitkä tuossa omassa kirjastossasi.

Tarkoituksenani ei ollutkaan kehittää mitää täysiveristä Ormia, vaan sellainen kevyt ja nopesti käyttöön otettava mahdollisuus tallentaa tietoja mysql kantaan, esim. vaikka ristinollan tilanteen, jolloin ei tarvitsisi projektiin linkittää raskaita kirjastoja.

feenix [15.03.2014 19:56:29]

#

EF ei sinänsä vaadi mitään liitännäisiä, sen kun linkkaa kirjastot ja kirjoitat koodilla mappaukset ja annat kannan tiedot. Eri asia jos haluat suoraan käyttää suunnittelukaluja tai suoraan kantarakenteista luoda luokat jne. Itse tykkään enemmänkin tehdä koodissa nuo.

Miten lazy loading vaatii ylimääräisen luokan? Viittausten lazy loading hoituu ihan virtual-merkinnällä, vai tarkoitatko jotain muuta lazy loadingia?

Minusta viittausavaimen arvon näkyminen luokassa ei ole kikkailu vaan ihan hyödyllinen ominaisuus. Aika usein sitä tarvitaan, eikä tarvitse turhaan sitten ladata viitattua oliota kannasta vain saadakseen ID:n selville.

Jos taas tarvitsee kätevää ja nopeaa tapaa tallentaa jotain tuollaisia pieniä tilatietoja, joista suurinta osaa ei tarvitse SQL:llä käsitellä, itse melkein tallentaisin vaikka JSONina. Voi nopeasti muodostaa sen mukaan oliot. En tiedä miten MySQL osaa tuota käsitellä, mutta pari tarpeellista hakukenttää riittää tekstikentän lisäksi, ellei kanta suoraan osaa JSONista niitä indeksoida.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta