Klassen und Properties

Toddi

Grünschnabel
Hallo,
ich habe eine Klasse mit einer privaten DataRow, in der die Daten der einzelnen Werte der Eigenschaften vorgehalten werden. Um die einzelnen Eigenschaften der Klasse so effizent wie möglich zu nutzen (z.B. für DataBinding), benötige ich zu jeder öffentlichen Eigenschaft auch den MaxLength-Wert aus dem Datenbankschema/ DataRow. Wie gesagt, die DataRow soll möglichst privat bleiben.

Klassenentwurf:
Code:
class Person
{
private DataRow _Dr;
		
public Person()
{
}

public string Vorname
{
get
{
return this._Dr["Vorname"].ToString()
}
set
{
this._Dr["Vorname"] = value;
}
}

public string Nachname
{
get
{
return this._Dr["Nachname"].ToString()
}
set
{
this._Dr["Nachname"] = value;
}
}
}
Zugriff sollte wenn möglich wie folgt aussehen:
Code:
Person _P = new Person();
_P.Vorname.Value = "Toddi";
_P.Vorname.MaxLength;
Hat jemand von euch eine Idee, wie ich das realisieren kann, ohne für jedes Property eine Klasse zu basteln?! Ich hatte es schon mit struct versucht, war aber auch nicht das Ideale.
Wenn ihr eine komplett andere Herangehensweise habt, währe ich für jede Idee sehr dankbar.

mfg t.a.
 
Hallo,

also wenn ich Dich richtig verstanden habe, willst Du Dir von Deiner DataRow per Property nicht nur den Wert sondern auch dessen maximale Länge zurückgeben lassen.

Da immer nur ein Wert returniert werden kann ist das so nicht möglich. Mein Vorschlag ist, weitere Properies einzufügen, die MaxLength zurückgeben.

Also:
Code:
class Person
{
   private DataRow _Dr;
		
   public Person()
   {
   }

   public string Vorname
   {
      get
      {
         return this._Dr["Vorname"].ToString()
      }
      set
      {
         this._Dr["Vorname"] = value;
      }
   }

   public string Nachname
   {
      get
      {
         return this._Dr["Nachname"].ToString()
      }
      set
      {
         this._Dr["Nachname"] = value;
      }
   }

   // Folgendes habe ich eingefügt
   
   public int MaxLaengeVN
   {
      get{return _Dr["Vorname"].MaxLength;}
   }

   public int MaxLaengeNN
   {
      get{return _Dr["Nachname"].MaxLength;}
   }
}

Ich hoffe, dass das Deine Frage beantwortet.

Grüße
Sir Raven
 
Hallo Sir_Raven!
Vielen Dank für Deine Antwort, hab schon gar nicht mehr damit gerechnet.
Diesen Gedanken hatte ich auch schon, aber da ist mir bei der Umsetzung der Aufwand viel zu groß, da ich mehrere Klassen mit mehr als 100 Eigenschaften zur Verfügung stellen muss. Wenn ich dann die MaxLength() Eigenschaft für jeden Datensatz veröffentliche ist der Aufwand schon verdoppelt und wenn ich dann vielleicht noch ein VornameChanged Feld einfügen möchte ist es das 3fache. Einfach zu komplex.

Ich hatte daher eher an eine zusätzliche, allgemeine Klasse DataField gedacht, in die ich eine Referenz des DataRowObjects reiche und den Feldnamen, welches von der Instanz verwaltet werden soll. Aber dann habe ich das Problem, das ich den Datentyp von Value (der den eigentlichen Wert des Datenfelds enthält) nicht individuell anpassen kann. Ich hab ja nicht nur Strings und für das Arbeiten mit den Klassen währe es schon besser, wenn ich jeden Datentyp jeder Eigenschaft in der Klasse festgelegt ist.
Hier ein Auszug aus der DataField-Klasse, die meiner Ansicht nach schon ein guter Ansatz ist:

Code:
	public class DataField
	{
		private DataRow _DataRowObject;
		private string _DataFieldName;

		public string Value
		{
			get
			{
				return this._DataRowObject[this._DataFieldName].ToString();
			}
			set
			{
				this._DataRowObject[this._DataFieldName] = value;
			}
		}

		public int MaxLength
		{
			get
			{
				return this._DataRowObject.Table.Columns[this._DataFieldName].MaxLength;
			}
		}

		public DataField(DataRow DataRowObject, string DataFieldName)
		{
			this._DataRowObject = DataRowObject;
			this._DataFieldName = DataFieldName;
		}
	}

Damit könnte ich jetzt für jede Eigenschaft in meiner Klasse Person eine Instanz der Klasse DataField erzeugen, habe aber dann das Problem, das alle Value-Felder den Datentyp string besitzen. Ich habe aber auch noch Datenfelder vom Typ DateTime, int, decimal usw. Hast Du eventuell dafür eine Idee?!
Das Einzige, was mir noch dazu einfällt, wäre den Datentyp von Value auf object zu setzen und dann mittels Typdeklaration darauf zuzugreifen, Beispiel:
((System.DateTime)_Person.Geburtstag.Value).ToShortDateString();
Ist aber auch blöd, da ich dann sämtliche Typen der einzelnen Felder immer sofort wissen muss.
:( Vielleicht bin ich auch zu anspruchsvoll, alles Mist. Ich weiß gar nicht, ob hier fluchen darf, hoffentlich.

Vielen Dank schon mal für die Hilfe...

mfg t.a.
 
Tja. wenn man Properties überladen könnte ...

Andere Idee: Statt den bishereigen Properties Methoden anlegen, in denen auch nur "return schlagmichtot;" steht und diese für die verschiedenen Typen überladen.

Was besseres fällt mir momentan nicht ein.

Grüße
Sir Raven
 
Wie arbeitest Du sonst mit großen Datenbankprojekten?! Greifst Du in den Forms direkt auf die DataSets, DataTables usw. zu oder achtest Du auch auf die Dreischichtigkeit Deiner Anwendungen (DataLayer, BusinessLayer und GUI)?!

Ich werd das dann erstmal mit dem object-Datentyp probieren und die Datentypen jeweils davor schreiben. Nervig, aber wenns nicht anders geht...

Auf jeden Fall vielen Dank für Deine Bemühungen und falls Dir doch noch was einfällt, sag bescheid...

mfg t.a.
 
Hallo Toddi,

tja, ich arbeite überhaupt nicht mit großen Datenbankprojekten da ich hautsächlich Spiele programmiere. Trotzdem achte ich bestmöglich auf die Dreischichtigkeit bei der Programmierung ... ok, bei kleineren Projekten bin ich manchmal zu faul dazu ... ;)

Grüße
Sir Raven
 
Das ist auch das Beste, wenn man darauf achtet und sich zur Einhaltung zwingt.

Für diejenigen die noch wissen wollen, wie ich mir geholfen habe:
Ich habe eine abstrakte Basisklasse DataFieldBase erstellt, die ein protected DataRow-Objekt (das Daten aus der Datenbank vorhält) verwaltet und alle gemeinsamen Eigenschaften wie MaxLength, Changed usw. public zur Verfügung stellt. Zusätzlich habe ich für jeden Datentyp, den ich benötige, eine Klasse (die von DataFieldBase erbt) erstellt und den entsprechenden Datentyp als "public string Value" beispielsweise zur Verfügung gestellt.
Ist anfangs ein wenig Aufwand, aber gerade bei größeren Klassen und Objekten, die Daten laden und speichern, lohnt sich meiner Ansicht der Aufwand. Man muss so nicht mehr wissen, welchen Datentyp die Datenbank erwartet und kann so die Daten für die Arbeit ideal konvertieren oder prüfen kann.

Hier die DataFieldBase-Klasse:
Code:
	public abstract class DbDataFieldBase
	{

		protected DataRow _DataRowObject;
		protected string _DataFieldName;

		protected bool _ValueChanged = false;
		public bool ValueChanged
		{
			get
			{
				return this._ValueChanged;
			}
			set
			{
				this._ValueChanged = value;
			}
		}

		public int MaxLength
		{
			get
			{
				return this._DataRowObject.Table.Columns[this._DataFieldName].MaxLength;
			}
		}

		public DbDataFieldBase(DataRow DataRowObject, string DataFieldName)
		{
			this._DataRowObject = DataRowObject;
			this._DataFieldName = DataFieldName;
		}
	}

Hier eine DataField-Klasse, die String-Werte verwaltet:
Code:
	public class DbDataFieldString:DbDataFieldBase
	{

		public string Value
		{
			get
			{
				return base._DataRowObject[base._DataFieldName].ToString();
			}
			set
			{
				base._DataRowObject[base._DataFieldName] = value;
			}
		}

		public DbDataFieldString(DataRow DataRowObject, string DataFieldName):base(DataRowObject, DataFieldName)
		{
		} 
}

Was mich noch interessiert, wie kann ich erzwingen, dass in der DataFieldString-Klasse die Eigenschaft Value implementiert werden muss?! Hab schon verschiedene Sachen probiert, mit virtual, abstract usw, aber ich darf den Datentyp der Eigenschaft in der Basisklasse beim Implementieren oder überschreiben nicht ändern. :( Dafür gibts doch bestimmt nen ganz billigen Trick, der mir momentan nur nicht einfällt.

Schönes Wochenende noch, bis dann

mfg Toddi
 
Zurück