Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
|Aisys| O/R Mapper
JuyJuka
myCSharp.de - Experte

Avatar #avatar-2316.jpg


Dabei seit:
Beiträge: 2282
Herkunft: Deutschland

Themenstarter:

|Aisys| O/R Mapper

beantworten | zitieren | melden

Beschreibung:
Objektrelationale Abbildung (englisch object-relational mapping, ORM) ist eine Technik der Softwareentwicklung, mit der ein in einer objektorientierten Programmiersprache geschriebenes Anwendungsprogramm seine Objekte in einer relationalen Datenbank ablegen kann.
Die hier veröffentlichte Komponente ist mein Versuch eine
- Allgemeingültige
- Generische
- Datenbankunabhänige
- Erweiterbare
und - Einfache
"lösung" dafür zur Verfügung zu stellen.

Ich versuch jetzt schon seit fast 2h einen brauchbaren Text zu schreiben, jetzt geb ich auf. Viel vergnügen mit der Assembly. Eine Dokumentation und Anleitung ist im Download enthalten. Ein paar andere Informationen gibts hier.

Ich freue mich auf jede Antwort.

Schlagwörter: ORM , O/R Mapper, OR Mapper, Objektrelationaler Mapper, Datenbankzugriff, Objektorientierung
Attachments
private Nachricht | Beiträge des Benutzers
GMLOD
myCSharp.de - Member

Avatar #avatar-2654.jpg


Dabei seit:
Beiträge: 1228

beantworten | zitieren | melden

Kannst du mal ein Codebeispiel zeigen, wie man komplexe Objektgraphen (z.B. M:N Relation) holt, bearbeitet und abspeichert?

Hast du die Performance schonmal gemessen?

Ich persönlich empfinde es als ungewohnt, dass alle Klassennamen, Attribute etc. Deutsche Namen tragen. Ich denke, Englisch ist hier als Industriestandard vorzuziehen.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von GMLOD am .
Shift to the left, shift to the right!
Pop up, push down, byte, byte, byte!

YARRRRRR!
private Nachricht | Beiträge des Benutzers
Khalid
myCSharp.de - Experte

Avatar #avatar-2534.gif


Dabei seit:
Beiträge: 3627
Herkunft: Hannover

beantworten | zitieren | melden

Zitat
Ich persönlich empfinde es als ungewohnt, dass alle Klassennamen, Attribute etc. Deutsche Namen tragen. Ich denke, Englisch ist hier als Industriestandard vorzuziehen.
Das ist mir auch negativ aufgefallen. Gerade, wenn man in einem internationalen Team arbeitet, scheidet sowas sofort aus. Ich würde ich alle deutschen Bezeichner ins englische übersetzen.
"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)
private Nachricht | Beiträge des Benutzers
JuyJuka
myCSharp.de - Experte

Avatar #avatar-2316.jpg


Dabei seit:
Beiträge: 2282
Herkunft: Deutschland

Themenstarter:

beantworten | zitieren | melden

Hallo @All,

Wer ein Beispiel sehen will:


using System;
using System.Data;

using Aisys;
using Aisys.ReflectionVersion;
using Aisys.ReflectionVersion.Implementation;

namespace Aisys.Beispiele
{
  [Implementation(
    DefaultImplementationType=typeof(Person),
    SelectType=typeof(Person)
    )]
  public interface IPerson : IAisysObject
  {
    DateTime Geburtstag { get; set; }
    string Name { get; set; }
    decimal PersonId { get; }
    Status Status { get; set; }
    string Vorname { get; set; }
  }

  [// Information, in welcher Tabelle die Datensätze abgelegt werden.
  Tabelle(/*Tabellen-Name*/"person")]
  [// Da keine Logik in der Datenbank sein soll und da nicht in jedem DBMS Autowerte möglich sind, 
   // werden Autowerte von der Anwedung vergeben. 
  AutomatischerWert("personid", "person")]
  [// Bestimmt, ob automatisch ein Protokoll über alle Felder geführt werden soll.
  Protokolliert(/*ja/nein==true/false*/true)]
  class Person : AisysObject, IPerson
  {
    #region Attribute
    // Normale Attribute für die Daten, mit standard Werten
    private decimal personId = decimal.MinValue;
    private string name;
    private string vorname;
    private DateTime geburtsdatum;
    private Status status;
    #endregion

    #region Konstruktoren
    // Standard Konstruktor
    public Person() : this(decimal.MinValue) { }
    // Einen Konstrucktor, mit dem man den Primärschlüssel voläufig/vorrübergehend setzen kann.
    // So kann man das Primärschlüssel-Property schreibgeschützt lassen und trotzdem Objekte nach dem Primärschlüssel selektieren.
    public Person(decimal personID)
      : this((DataRow)null)
    {
      this.personId = personID;
    }
    // Dieser Konstruktor ist optional, erlaubt der Aisys.DLL aber ein schnelleres, saubereres und sichereres Arbeiten.
    protected Person(DataRow dr) : base(dr) { }
    #endregion

    [// Makierung für Spalten, die zum Primärschlüssel gehören.
    Id]
    [// Information, in welcher Spalte der Wert abgelegt wird.
    Spalte(/*Spaltenname*/"personid")]
    public decimal PersonId
    {
      get { return this.personId; }
      private set { this.VerursachePropertyChanged("PersonId", ref this.personId, ref value); }
    }

    [// Information, in welcher Spalte der Wert abgelegt wird.
    Spalte(/*Spaltenname*/"nachname")]
    public string Name
    {
      get { return this.name; }
      set { this.VerursachePropertyChanged("Name", ref this.name, ref value); }
    }

    [// Information, in welcher Spalte der Wert abgelegt wird.
    Spalte(/*Spaltenname*/"vorname")]
    public string Vorname
    {
      get { return this.vorname; }
      set { this.VerursachePropertyChanged("Vorname", ref this.vorname, ref value); }
    }

    [// Information, in welcher Spalte der Wert abgelegt wird.
    Spalte(/*Spaltenname*/"geburtstag")]
    public DateTime Geburtstag
    {
      get { return this.geburtsdatum; }
      set { this.VerursachePropertyChanged("Geburtstag", ref this.geburtsdatum, ref value); }
    }

    [// Information, in welcher Spalte der Wert abgelegt wird.
    Spalte(/*Spaltenname*/"status")]
    public Status Status
    {
      get { return this.status; }
      set { this.VerursachePropertyChanged("Status", ref this.status, ref value); }
    }

  }

  public enum Status
  {
    Aktiv = 0,
    InAktiv = 1
  }
}

Gruß
Juy Juka
private Nachricht | Beiträge des Benutzers
Razer
myCSharp.de - Member

Avatar #avatar-2389.jpg


Dabei seit:
Beiträge: 84
Herkunft: BW/DE

beantworten | zitieren | melden

In der Doku springt mir spontan das "Entwiklerhandbuch" ins Auge
private Nachricht | Beiträge des Benutzers
Razer
myCSharp.de - Member

Avatar #avatar-2389.jpg


Dabei seit:
Beiträge: 84
Herkunft: BW/DE

beantworten | zitieren | melden

Hallo JuyJuka,

an welche Stellen würdest du nun die Geschäftslogik packen?
In die Klassen selbst? In externe Manager-Methoden?

Gruß,
Razer
private Nachricht | Beiträge des Benutzers
gordon2001
myCSharp.de - Member



Dabei seit:
Beiträge: 219
Herkunft: Mecklemburg-Vorpommern

beantworten | zitieren | melden

Bitte nicht falsch verstehen aber warum willst du estwas neu erfinden was es schon komplett ausgearbeitet und erprobt gibt siehe NHibernate oder ADO.Net

http://www.hibernate.org/343.html (NHibernate)
http://msdn.microsoft.com/de-de/library/bb979090.aspx (ADO.Net)
private Nachricht | Beiträge des Benutzers
Razer
myCSharp.de - Member

Avatar #avatar-2389.jpg


Dabei seit:
Beiträge: 84
Herkunft: BW/DE

beantworten | zitieren | melden

Wenn man als Entwickler ledeglich den SQL-Server als Plattform berücksichtigen muss, denke ich außerdem, dass z.B. LINQ to SQL in mancher Hinsicht einfach mächtiger ist - Stichworte wären LINQ to SQL, Concurrency Exceptions, Designer-Unterstützung, Support...

Wie werden den Updates mit deinem OR-Mapper eigentlich gemanaged?
Ich denke du speicherst eine Art RowState für jedes Objekt, welches durch die Ableitung von AisysObject bereitgestellt wird, oder?
Habe in deiner Doku nichts dazu gefunden.

Die Mischung aus englischen und deutschen Methoden- und Eventbezeichnungen finde ich persönlich ziemlich unschön und weniger hilfreich, ich denke dass du da mit etwas Refactoring mehr Stil erreichen kannst.

Nichtsdestotrotz erscheint mir deine Komponente ansonsten sauber aufgebaut, soweit ich dass mit meinen (doch deutlich bescheideneren) Kentnissen beurteilen kann.

Gruß,
Razer
private Nachricht | Beiträge des Benutzers
JuyJuka
myCSharp.de - Experte

Avatar #avatar-2316.jpg


Dabei seit:
Beiträge: 2282
Herkunft: Deutschland

Themenstarter:

beantworten | zitieren | melden

Hallo,

@Razer: Mein OR-Mapper verwendet intern ADO.NET, hat also desen standard Verhalten. In der Doku ist dazu nichts zu finden, weil dass für die Benutzung vollkommen irrelevant und nur verwirrend ist.

Das ich Englisch und Deutsch gemischt habe ist blöd. Geplant war reines Deutsch. Aber Framework-Klassen sind nun mal Englisch und wenn ich mich auf solche beziehe (z.B. System.Activator) blieb mir nichts anderes übrig. Außerdem hat unsere Qualitätssicherung hier ziemlich geschlafen. :-(

Die Geschäftslogik gehört meiner Ansicht in die Klassen, da Daten und Funktion in der OO eine Einheit bilden. Außerdem ist der Datenzugriff ja sauber in der Aisys.dll enthalten und nicht in den Klassen, die du schreibst.
Bei bedarf kann man die Funktion noch auslagern aber dazu sollte es schon einen Grund geben.

@gordon2001: Bei NHibernate kannte ich damals kein Active-Recorde-Aufsatz und zusammen mit dem Mapping per Xml-Datei war das für mich inakzeptabel.
ADO.NET ist kein OR-Mapper! DataTable und Co. sind für die verwendung innerhalb der Funktionsschicht oder gar auf der Präsentationsschicht schreklich (siehe auch typed oder untyped Dataset ).

Und die Frage "Warum" hab ich auch schon mal hier beantwortet: |Aisys| O/R Mapper

Gruß
Juy Juka
private Nachricht | Beiträge des Benutzers
gordon2001
myCSharp.de - Member



Dabei seit:
Beiträge: 219
Herkunft: Mecklemburg-Vorpommern

beantworten | zitieren | melden

Wenn du sagtst ADO.Net hat kein O/R Mapper liegst du sowas von falsch. ansonnsten hätte ich die letzten zwei Projekte in meiner Firma mit etwas nicht vorhandenen Umgesetz :D
private Nachricht | Beiträge des Benutzers
FZelle
myCSharp.de - Experte



Dabei seit:
Beiträge: 10084

beantworten | zitieren | melden

Da verwechselst du aber etwas.

ADO.NET ist die Programmierschnittstelle, zum zugriff auf DB's per DBConnections,
DBCommands und DBAdapter.
Da ist kein ORMapper vorhanden.

Du meinst evtl EF oder LinQ2Sql.
private Nachricht | Beiträge des Benutzers
JuyJuka
myCSharp.de - Experte

Avatar #avatar-2316.jpg


Dabei seit:
Beiträge: 2282
Herkunft: Deutschland

Themenstarter:

beantworten | zitieren | melden

Hallo gordon2001,
Zitat von gordon2001
... ADO.Net hat kein O/R Mapper ...
Ich sagte aber:
Zitat von gordon2001
... ADO.Net ist kein OR-Mapper ...
Natürlich gibt es viele O/R Mapper, die auf ADO.NET aufbauen ... [sarkasmus]lass mal überlegen, mit fällt grade kein Beispiel ein[/sarkasmus].

Gruß
Juy Juka
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

Und damit lasst es an dieser Stelle mal gut sein. In ".NET-Komponenten und C#-Snippets" bitte immer mit Blick auf den Benutzer des Snippets schreiben. Was braucht der für Informationen., um das Snippet einsetzen zu können. Er soll sich nicht durch lange Diskussionen zu Randthemen wühlen müssen.
private Nachricht | Beiträge des Benutzers