Laden...

Forenbeiträge von Fracoon Ingesamt 85 Beiträge

08.07.2008 - 14:02 Uhr

Ich glaub ich hab eine echt tolle Lösung gefunden. Wenn alles funzt und ich genug Zeit habe stell ich sie hier noch rein.

08.07.2008 - 14:00 Uhr

Das ist mir klar. Die Daten liegen jedoch nicht in einer Datatable sondern in Objekten vor (siehe Oben). Also müsste ich die Daten zuerst aus den Objekten in eine Datatable kippen.

08.07.2008 - 09:03 Uhr

Am ende musst du die Datenquelle natürlich noch an den DataGridView binden =)

Genau diese möglichkeit würde ich mir doch dann nehmen?!?! Mit Databinding hat das ja nichts mehr zu tuen. Und mit einem DataAdapter kann ich dann auch nichtm ehr arbeiten?!?!

07.07.2008 - 23:24 Uhr

Ansonsten muß das ganze komplett generisch sein.

Genau. Das ist das Problem.

Ich habe nichtmal ansatzweise eine Idee wie ich es realisieren könnte.

07.07.2008 - 15:26 Uhr

verwendetes Datenbanksystem: Postgres

Hi@all...

ich hoffe ich bin im richtigen Forum. Wenn nicht bitte verschieben.

Es geht um Folgendes :

Ich habe eine Klasse die eine List<> von einer anderen Klasse enthält. Etwa so :


class Probe
{
      public string Journalnummer;
      public string Schale;
      public List<Messung> messungen;

}

class Messung
{
      public string name;
      public string ergebnis;
}

Beispiel mit Daten:



Probe probe1 = new Probe();
probe1.Journalnummer = "1002";
probe1.Schale = "A1"

Messung messung1 = new Messung();
messung1.name = "Leer";
messung1.ergebnis = "11.11";

Messung messung2 = new Messung();
messung2.name = "Voll";
messung2.ergebnis = "11.11";

probe1.messungen.add(messung1);
probe1.messungen.add(messung2);

Probe probe2 = new Probe();
probe2.Journalnummer = "1003";
probe2.Schale = "A4"

Messung messung3 = new Messung();
messung3.name = "Leer";
messung3.ergebnis = "11.11";

Messung messung4 = new Messung();
messung4.name = "Verbrannt";
messung4.ergebnis = "11.11";

probe2.messungen.add(messung3);
probe2.messungen.add(messung4);

Jetzt würde ich gerne in einer Tabelle wie die im Anhang haben. Also für jede Messung in der Liste muss (wenn nicht schon von einer anderen Probe erstellt) eine Spalte erstellt werden. Am besten noch mit DataBinding, dass die Messungen beim Eintragen automatisch in der Probe erstellt werden.

In meinem Beispiel fehlt z.B. bei der zweiten Probe der "Voll" Wert aber ein "Verbrannt" werd ist hinzugekommen der wiederum in der ersten Probe fehlt.

Ich hoffe ich habe mein anliegen klar ausgedrückt. Ich hab auch schon sehr viel über Google und im Forum gesucht. Aber ohne erfolg.. Kennt jemand eine Möglichkeit dies zu realisieren?

30.05.2008 - 17:50 Uhr

Hallo Norbert,

bin ein WCF Neuling, aber beschäftige mich grade mi etwas verlgeichbarem.
Sieh Fein justierbare Authentifizierung in WCF??


1. Nicht jeder soll sich mit dem Service verbinden dürfen.
Wie kann man dies am einfachsten Realisieren ?

Ich löse das über die Windows Authentifizierung. Die kann man in der wcf Konfiguration einstellen.


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="HelpDeskSRV.Test" behaviorConfiguration ="DefaultTCP">
        <host>
          <baseAddresses>
            <add baseAddress ="http://192.168.2.23:8000/HelpDeskSRV"/>
          </baseAddresses>
        </host>
        <endpoint address="net.tcp://192.168.2.23:2310/Test" binding="netTcpBinding" bindingConfiguration ="DefaultTCP" contract="HelpDeskSRV_API.ServiceContracts.ITest"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="DefaultTCP">
          <serviceMetadata httpGetEnabled="True" policyVersion="Policy15" />
          <!-- <serviceMetadata httpGetEnabled="True" policyVersion="Policy15" /> -->
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <netTcpBinding>
        <binding name ="DefaultTCP">
          <security mode ="Transport">
            <transport clientCredentialType ="Windows" />
            <message clientCredentialType ="Windows"/>
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
  </system.serviceModel>
</configuration>

(Nur ein Test =))

Soweit ich weiß kann man für WCF auch eigene Authentifizierungsdienste schreiben, die dann in deinem Fall die Tabelle mit den Usern abfragen könnte.

  1. Wenn man sich verbunden hat und eine Funktion aufruft, dann muß innerhalb der Funktion in abhängigkeit dieses Benutzers ggf ein leicht unterschiedliches (eben benutzerabhängiges) Verhalten implementiert werden.
    Hier könnte ich zwar beim Aufruf der Funktion jeweils von außen den Benutzer mit übergeben, aber das ist recht nervig, weil es später sehr viele Services geben wird.

Funktioniert bei mir so :


class Test : ITest
    {
        
        #region ITest Members
        
        public Boolean logtest(string bla)
        {
            string username;
            Permissions s = Permissions.getInstance();
            username = ServiceSecurityContext.Current.WindowsIdentity.Name;

            if (!s.Users[username].Contains(permissions.callTest))
            {

                throw new FaultException<SecurityFault>(new SecurityFault("Access Denied"));
                
                //throw new FaultException("Access Denied");
            }

            Console.WriteLine(username + " identified");

            return true;
        }

Dazu ist zu sagen, dass man den für den Service die Sessions aktivieren muss. Sonst kann man nicht bestimmen welcher Benutzer gerade verbunden ist.

Ich hoffe ich konnte dir ein wenig helfen.

28.05.2008 - 23:39 Uhr

Vielen dank für die Zeit die du dir nimmst Rainbird...

Irgendwie habe ich das Gefühl wir reden aneinander vorbei.

Ich wollte wissen ob es eine bessere Möglichkeit gibt PRO METHODE Sicherheitsrichtlinien zu implementieren. Aus deinem ersten Posting entnehme ich, dass du denkst dass es über ein Ticket besser gelöst werden kann.

Ich vermute aber folgendes : Das verhalten was bei dir durch das Ticket erreicht wird, macht bei mir der WCF Service von ganz alleine. Ich habe ihn so konfiguriert, dass nur Benutzer die es auch in Windows gibt eine Session aufbauen können.

Die Rechteprüfung kommt aber erst dann überhaupt zum Einsatz, wenn ein Benutzer sich erfolgreich angemeldet hat. Benutzer ohne gültige Sitzung haben von vorn herein keine Rechte.

Bei mir : Wer nicht über ein gültiges Windows Konto verfügt hat von vorn herein keine Rechte.

Um eine rollenbasierte Sicherheit zu haben, muss die nötige Rolle natürlich bei jedem Funktionsaufruf geprüft werden

Genau das tue ich. Unabhängig von der Windows Gruppe in der sich jemand befindet. Die Berechtigungsprüfung findet über meinen Permissions Singleton statt.

Hinzu kommt, dass die Identität des Aufrufers bei einer Aufrufkette über mehrere Dienste (Also Dienst A konsumiert intern Dienst B) nicht weitergegeben wird (Der Aufruf von Dienst B würde im Kontext des AppServer-Dienstkontos laufen). Also wird ein Ticket benötigt, welches man an den Aufrufkontext hängt. Der Sicherheitsdienst zieht dann die gespeicherte Benutzeridentiät der Sitzung heran (welche er anhand der Ticketkennung ermittelt) Bei mehreren Hops hätte der Sicherheitsdienst arge Probleme, den ursprünglichen Client-Benutzer herauszufinden. Bei mehreren Applikationsservern könnte man die Sitzungsliste auf replizieren. Das Ticket ist also nur für die Authentifizierung nützlich, aber nur indirekt für die eigentliche Rechteprüfung.

Darüber habe ich mir noch keine Gedanken gemacht. Könnte mir aber vorstellen das WCF da auch eine Integrierte Lösung bereithällt.

Ich würde also sagen das unser Ansatz sehr ähnlich ist. Dein Ansatz ist nur etwas vorausschauender?!?!?!?

28.05.2008 - 20:18 Uhr

Hallo Rainbird,

vielen Dank für deine Antwort. Ich habe mir deinen Applikationsserver mal angesehen. Kann aber nicht ganz verstehen wo der Vorteil gegenüber meiner Lösung sein soll.

Machst du nicht an dieser stelle "genau" das selbe wie ich?


// Wenn der Aufrufer in der Rolle "Product Reader" ist ...
if (ApplicationServer.IsInRole("Product Reader";))
{
// Aufruf an Geschäftslogik delegieren
return new ProductManager().GetProduct(productID);
}

Um nochmal kurz meine Situation zu beschreiben (vieleicht war es etwas unklar) :

Hier ist der Auszug von dem ich denke, dass er dem Ansatz von dir sehr Ähnlich ist


string username;
Permissions s = Permissions.getInstance();
username = ServiceSecurityContext.Current.WindowsIdentity.Name;

if (!s.Users[username].Contains(permissions.call_logtest)
{
//TODO : Zugriffsverweigerung an Client melden, Methode beenden (Mit Exception??)
}

"Permissions" ist ein Singleton, welcher ein Dictionary enthält. In diesem Dictionary steht der Benutzername (String) als Key und eine List von Rechten (Gebildet aus einem ENUM).
Um den Dienst überhaupt nutzen zu können, muss der Clientuser auf dem Rechner auf dem der Server läuft angelegt sein.

Kannst du mir bitte erklären wo der Vorteil des von dir genannten Tickets besteht? Ich steig nicht dahinter, weil es für mich so aussieht als würdest du (genau wie ich) in jeder Methode des Dienstes eine Gruppenzugehörigkeit abfragen).

27.05.2008 - 19:32 Uhr

Hi@all,

ich möchte gerne eine Serveranwendung schreiben die WCF benutzt um mit den Clients zu kommunizieren.

Das nur in Windows bekannte Benutzer zugriff auf den Service-Host haben ist mir bereits gelungen. Ist auch so gewollt.

Jetzt hätte ich aber gerne eine feinere Kontrolle darüber welcher User was machen darf.

Das ganze sollte auf Methodenebene einstelbar sein.

So ist die Lösung die ich mir ausgedacht habe :


class Test : ITest
    {
        #region ITest Members
        
        public Boolean logtest(string bla)
        {
            string username;
            Permissions s = Permissions.getInstance();
            username = ServiceSecurityContext.Current.WindowsIdentity.Name;

            if (!s.Users[username].Contains(permissions.call_logtest)
            {
                //TODO : Zugriffsverweigerung an Client melden, Methode beenden (Mit Exception??)
            }

            return true;
            
        }

        #endregion
    }

Innerhalb des Methodenaufrufs im Service wird also überprüft ob der User berechtigt ist die Methode testlog aufzurufen (permissions.call_logtest)

Somit könnte ich wirklich auf Methodenebene steuern ob ein User berechtigt ist oder nicht.

Was ich nicht schön an dieser Lösung finde ist, dass der Benutzer wirklich bei jedem aufruf von logtest überprüft wird.

Gibts ne schönere Lösung?

21.04.2008 - 12:22 Uhr

Nein Sorry... habe mich bis jetzt noch nicht intensiv mit hql beschäftigt... nur mit den mapping und dem persistieren von objekten!

20.04.2008 - 10:51 Uhr

Hallo Spike24,

bin zwar noch nicht der Hibernate Experte, aber ich habe ähnliche Erfahrungen gemacht wie du.

Meiner Meinung nach ist das von dir beschriebene Verhalten "normal". Du musst dem Child den Parent "zuweisen". Am besten bevor du commitest.

Ich bin mir da relativ sicher, da ich das Probloem selbst hatte und über Google mehrere Quellen gefunden habe die das Verhalten als "normal" bezeichnen!

18.04.2008 - 19:37 Uhr

Pack doch einfach 2 oder 3 Grafikkarten mit jeweils 2 Anschlüssen in einen Rechner.. Dann brauchst deine Anwendung nicht verteilen =)

26.03.2008 - 12:01 Uhr

Danke =)

hab mir in der zwischenzeit mal das wcf etwas angeschaut. Finde jedoch nur wirklich Einführungs Tutprials. Kennt jemand was, das etwas tiefgreifender das WCF behandelt?

25.03.2008 - 12:35 Uhr

Hallo Rainbird,

mit deiner Antwort habe ich gerechnet, da ich deinen Applikationsserver schon gesehen und getestet habe =).

Vielen Dank für deine Antwort. Verstehe ich dich also richtig? Du sagst ein Applikationsserver ist also in jedem fall dem direkten zugriff vorzuziehen?

24.03.2008 - 10:27 Uhr

Hi@all,

hab da mal wieder ne Frage =).

Was ist schneller? Warum? und Wieviel?

  1. Clientapplikation greift direkt auf einen MSSql 2005 Server mittels LinqToSQL oder NHibernate zu,

  2. Client greift auf einen Server mit WCF zu um sich die Daten aus der DB zu holen. Der Server holt die Daten mittels Linq oder NHibernate aus der Datenbank und stellt sie mittels WCF zur verfügung.

Ich würde gerne WCF benutzen:

  • um dann auf der "Serverebene" Berechtigungen zu vergeben
  • Die authentifizierung durchzuführen
  • Eine "Locking" funktionalität zu Implementieren, sodass Datensätze nur einmal zum bearbeiten geöffnet werden können.

Welche Nachteile hätte ich mit WCF gegenüber dem direkten Datenbankzugriff?
Möglichkeit 1 habe ich schon ausprobiert. Mein Hauptproblem hierbei ist, dass man so keine Datensätze auf vernünftigem Weg sperren kann!

Bevor ich mich jetzt in Möglichkeit 2 stürze wollte ich mal eure Meinungen hören.

Oder ist eine Kombination aus beidem denkbar / sinnvoll?

16.03.2008 - 17:51 Uhr

Das ist ein komplexeres Problem.

Willst Du wirklich die ganze liste Clonen?
Macht das sinn?

Sinn des ganzen wäre, dass ich für den gesamten Kunden eine "Undo" Funktion habe! (wenn man auf Abbrechen im Bearbeiten-Fenster klickt)!!

15.03.2008 - 00:27 Uhr

Danke FZelle für die tipps!

Hab jetzt mit meiner implementierung noch ein anderes problem!

Hab BEginEdit CancelEdit und EndEdit nun in eine eigene Klasse gepackt. Meine Kunde und Ansprechpartner erben davon!

Funtioniert soweit!

Aber : Der Kunde hat eine List<ansprechpartner>. Für die geht es nicht. Ich vermute, dass beim "kopieren" der Properties für List<> nur eine Referenz übergeben wird!
Ist das richtig? Kann man das irgendwie so generisch lösen wie für die anderen Properties?

14.03.2008 - 19:12 Uhr

Für alle die es interessiert, ich hab jetzt folgendes gemacht :


public class ansprechpartner : IEditableObject
    {
        Hashtable props = null;
        
        private long ansprechpartner_id;
        private string vorname;
        private string nachname;
        private string email;
        private string telefon;
        private kunde kunde_fk;
        private int version;


        #region Fields
        public virtual long Ansprechpartner_id
        {
            get { return ansprechpartner_id; }
            set { ansprechpartner_id = value; }
        }
        
        public virtual string Vorname
        {
            get { return vorname; }
            set { vorname = value; }
        }
        
        public virtual string Nachname
        {
            get { return nachname; }
            set { nachname = value; }
        }
        
        public virtual string Email
        {
            get { return email; }
            set { email = value; }
        }
        
        public virtual string Telefon
        {
            get { return telefon; }
            set { telefon = value; }
        }
        public virtual kunde Kunde_fk
        {
            get { return kunde_fk; }
            set { kunde_fk = value; }
        }
        public virtual int Version
        {
            get { return version; }
            set { version = value; }
        }
 
        #endregion

        public virtual void BeginEdit()
        {
            

            //enumerate properties

            PropertyInfo[] properties = (this.GetType()).GetProperties
                        (BindingFlags.Public | BindingFlags.Instance);

            props = new Hashtable(properties.Length - 1);

            for (int i = 0; i < properties.Length; i++)
            {
                //check if there is set accessor

                if (null != properties[i].GetSetMethod())
                {
                    object value = properties[i].GetValue(this, null);
                    props.Add(properties[i].Name, value);
                }
            }
        }
        public virtual void CancelEdit()
        {
            //check for inappropriate call sequence

            if (null == props) return;

            //restore old values

            PropertyInfo[] properties = (this.GetType()).GetProperties
                (BindingFlags.Public | BindingFlags.Instance);
            for (int i = 0; i < properties.Length; i++)
            {
                //check if there is set accessor

                if (null != properties[i].GetSetMethod())
                {
                    object value = props[properties[i].Name];
                    properties[i].SetValue(this, value, null);
                }
            }

            //delete current values

            props = null;
        }
        public virtual void EndEdit()
        {
            //delete current values

            props = null;
        }



        
    }

Funktioniert bist jetzt ganz gut! Unf vor allem muss man nicht für jede Property die man hinzufügt noch etwas an der "Transaktionslogik" ändern!

Edit : Ist übrigens von Codeproject "geklaut"!

14.03.2008 - 18:15 Uhr

Danke für den Tipp FZelle.

Ich vermute mal wenn bei ie.CancelEdit(); eine NullReference Exception kommt, heißt das, dass die Klasse IeditableObject nicht implementiert?!!?

13.03.2008 - 21:19 Uhr

Schau ich mir an danke!

13.03.2008 - 21:11 Uhr

Hab jetzt was ähnliches wie deinen 2. Lösungsansatz implementiert :

Hab mir in der Ansprechpartner Klasse eine Statische methode geschrieben die einen Ansprechpartner mit einem anderen vergleicht und veränderte werte überschreibt.

Bevor nun das Bearbeiten fenster geöffnet wird erstelle ich einen neuen Ansprechparter un jage ihn zusammen mit dem "originalen" ansprechpartner durch diese methode. So bekomme ich eine "Kopie". Wenn der Benutzer dann auf Übernehmen klickt mache ich das ganze umgekehrt. Wenn er abbrechen klickt passiert nichts..

Ist halt ein "hoher" Aufwand wenn der Ansprechpartner Klasse felder hinzugefügt werden sollen!

Aber denke so bin ich auf dem sichersten weg!

13.03.2008 - 19:44 Uhr

Danke fü die Antwort. Hab grade gemerkt das die serialisierung tatsächlich nicht funktioniert wenn das Objekt aus der Datenbank kommt...

zu deinen Lösungsvorschlägen :

zu 1 : Wie geht das? Klingt sehr interessant wenn es einfach zu implementieren ist!
zu 2 : Hab ich mir auch shcon gedacht. Ist aber bei Objekten mit vielen Properties ein RIESEN aufwand!
zu 3 : auch seeeehr viel Aufwand!

13.03.2008 - 19:21 Uhr

Hab jetzt folgendes gemacht :

Das Ansprechpartner-Objekt wird zuerst mitels Evict aus dem NHibernate cahe entfernt und dann mit dem neuen Objekt ersetzt.

Funktioniert!

Würde mich aber trotzdem über antworten freuen... gibt bestimmt bessere methoden!

13.03.2008 - 18:24 Uhr

verwendetes Datenbanksystem: Postgres

Hi@all...

ich habe eine Klasse Kunde mit einer "List" von ansprechpartner (klasse).

Die Ansprechpartner lass ich mir in einem Datagrid anzeigen.
Habe einen bearbeiten Button, der einen Dialog öffnet indem ich den Ansprechpartner bearbeiten kann. Zur Zeit übergebe ich das Ansprechpartner Objekt an den Dialog und mach ein Databinding an Textboxen. Wenn ich nun Felder verändere werden sie direkt um Objekt verändert. Ich hätte aber gerne einen Abbrechen Button der die Änderungen dann verwirft!

Hab hier und auch bei Codeplex schon einige interessante Artikel zum Thema "Transaktionen auf Objektebene" gelesen. Ist aber alles sehr kompliziert.

Was ich schon versucht habe ist : Objekt Serialisieren => an Dialog übergeben => nur bei OK das Objekt aus der Liste mit dem geänderten Objekt ersetzen.
Das funktioniert soweit auch.

ABER! Ich benutze NHibernate. Beim Speichern des Objekts (Kunde) wirft er eine Exception, dass ein Objekt mit der gleichen ID bereits existiert.

Hat jemand ne Idee wie ich das lösen könnte?

03.03.2008 - 13:53 Uhr

Vielen Dank FZelle für dein endloses Engagement. 👍

Meine Frage ist damit vorerst mal beantwortet. Ich werde wahrscheinlich in meinem Lernprozess auf noch viele andere Fragen stoßen und freue mich, dass es einen Ort wie diesen hier gibt!!

02.03.2008 - 18:33 Uhr

ok eine Sache ist mir jetzt noch aufgefallen. Mit dieser Methode bekomme ich immer alle Properties. Macht ja nicht unbedingt immer sinn, weil manche Properties durch den Benutzer gar nicht geändert werden können. Kann ich properties in einer Klasse "Markieren" um diese Markierung später auszuwerten?

Also ob das Attribut im Vergleich angezeigt werden soll oder nicht?!?!

02.03.2008 - 16:23 Uhr

Hab mir das ganze jetzt mal o zurecht gelegt :


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            test org = new test();
            test db = new test();
            test changed = new test();

            org.Id = 1;
            org.Nachname = "BlaBLubb";
            org.Name = "Hans";

            db.Id = 1;
            db.Nachname = "Mustermann";
            db.Name = "Hans";

            changed.Id = 1;
            changed.Nachname = "Wurst";
            changed.Name = "Hans";
            
            Type t = typeof(test);

            foreach (System.Reflection.PropertyInfo pi in t.GetProperties())
            {
                
                Console.WriteLine(pi.Name + " | " + pi.PropertyType);
                Console.WriteLine("Original   : " + pi.GetValue(org, null).ToString());
                Console.WriteLine("DB-Value   : " + pi.GetValue(db, null).ToString());
                Console.WriteLine("Your-Value : " + pi.GetValue(changed, null).ToString());
                Console.WriteLine();
            }

            Console.ReadLine();

        }
    }

    class test
    {
        private int id;

        public int Id
        {
            get { return id; }
            set { id = value; }
        }
        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        private string nachname;

        public string Nachname
        {
            get { return nachname; }
            set { nachname = value; }
        }
    }
}

sieht eigentlich ganz net aus. Wenn ich das jetzt in eine Funktion packe die 3 Objecte entgegennimmt könnte ich mir ja aufgrund der einzellnen Typen eine GUI generieren lassen (String,Integer = Textbox,Bool = Checkbox)
In der könnte man dann alle 3 Versionen des objects anzeigen und den Benutzer entscheiden lassen was er tut.

Klingt gut oder?

02.03.2008 - 04:42 Uhr

Tja, gute frage.
Ich lese dann den neuen Datensatz ein, habe für meinen ORMapper dann eine Funktion, die generisch
die Objekte vergleicht, und mir eine Liste der Änderungen bietet.
Die kann ich dann ganz oder je nach Wunsch teilweise ausgeben.

hört sich interessant an!! Mir (als "Anfänger") drängt sich jedoch die Frage auf :

Wie kann ich für VERSCHIEDENE Objekte/Klassen generisch die Attribute vergleichen? Ohne diese in der generischen funktion angeben zu müssen? Hast vieleicht nen Link? oder Codeschnippsel für mich?

01.03.2008 - 15:42 Uhr

Ok, hab mitlerweile die "versionierung" vin nhibernate eingebunden. funktioniert gut.

Aber für einen Endanwender wäre es natürlich unschön wenn er viele änderungen vornimmt, um dann festzustellen, dass er nicht speichern kann weil eine concurency Exception auftritt.

Wie geht man damit um? Muss ich für alle verschiedenen Datensätze die man Speichern kann eine "vergleichsroutine" schreiben bei der man dann die differenzen sehen und dementsprechend reagieren kann?
Oder kann man sowas generisch für alle schreiben irgendwie?

Finde die Lösung mit der concurency Exception zwar gut, für den Endanwender in gewissen Fällen aber eher unschön.

Wie kann man sowas handhaben?

29.02.2008 - 11:54 Uhr

vieleicht noch ergänzend warum ich das frage:

Das datenbankeigene Locking funktioniert immer nur innerhalb einer Transaktion(oder?)

Ich würde es in meiner Applikation gerne verwenden habe jedoch nur eine Globale Session (Singleton)

Wenn ich jetzt mehrere z.B. Kunden zum bearbeiten öffne bräuchte ich ja mehrere Transaktionen damit das Locking funktioniert?!?!

29.02.2008 - 11:52 Uhr

verwendetes Datenbanksystem: postgres

Hi@all,

hab da mal ne Frage:

Kann eine NHibernate ISession immer nur eine ITransaction verwalten? Hab über google schon verschieden Aussagen gefunden. Aber nichts eindeutiges.

Wenn mehrere gehen sollten, wie kann ich dann festlegen was in welcher Transaction ausgeführt wird? (Schon alleine desswegen geh ich davon aus das es generel nicht geht??!)

28.02.2008 - 19:15 Uhr

Ok. Habs selbst gelöst :


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            test bla = new test();
            bla.Nachname = "bla";
            bla.Vorname = "blubb";

            List<test> liste = new List<test>();
            liste.Add(bla);

            DataGridViewTextBoxColumn col = new DataGridViewTextBoxColumn();
            col.Name = "Vorname";
            col.DataPropertyName = "Vorname";
            col.HeaderText = "Vorname";

            dataGridView1.Columns.Add(col);
            dataGridView1.DataSource = liste;
        }
    }

    public class test
    {
        string vorname;

        public string Vorname
        {
            get { return vorname; }
            set { vorname = value; }
        }
        string nachname;

        public string Nachname
        {
            get { return nachname; }
            set { nachname = value; }
        }

        
    }
}

28.02.2008 - 17:36 Uhr

Hi@all...

ist wahrscheinlich nur ne kleinigkeit:

ich will eine Klasseninstanz an ein Datagridview binden. Funktioniert auch so:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            test bla = new test();
            bla.Nachname = "bla";
            bla.Vorname = "blubb";

            List<test> liste = new List<test>();
            liste.Add(bla);
            dataGridView1.Columns.Add("Vorname", "Vorname");
            dataGridView1.DataSource = liste;
        }
    }

    public class test
    {
        string vorname;

        public string Vorname
        {
            get { return vorname; }
            set { vorname = value; }
        }
        string nachname;

        public string Nachname
        {
            get { return nachname; }
            set { nachname = value; }
        }
    }
}

aber warum taucht die Vorname Spalte dann doppelt auf? Wenn ich an eine Datatable binde werden schon vorhandene Spalten nicht neu erstellt!

27.02.2008 - 16:45 Uhr

Laut offizeller Doku nicht. Dort ist zu mindest kein "lazy"-Attribut für das <property>-Element erwähnt.

Probiers aus:

<property name="Telefon" column="telefon" lazy="false"/>  

Warscheinlich wirds aber nicht gehen.

Grüße,
Alex

Das seltsame ist, dass das Feld welches die Änderungen nicht aktzeptiert gar nicht gemappt wird!

27.02.2008 - 15:13 Uhr

kann man bestimmte felder vom Lazy Loading ausschließen?

27.02.2008 - 15:09 Uhr

Danke funktioniert. Also hat man mit Lazy Loading keine chance??

27.02.2008 - 14:34 Uhr

verwendetes Datenbanksystem: postgres

Hi@all

ich arbeite mich gerade in NHibernate ein und bin nun auf ein Problem gestoßen.

Ich habe eine Business Object Klasse :


using System;
using System.Collections;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace NHibKunde.DBClasses
{
    abstract public class BusinessObject
    {
        #region Public interface

        public BusinessObject()
        {
            // Broken business rules.
            // No duplicates allowed
            // so store rules by key.
            brokenRules = new Hashtable();
        }

        /// <summary>
        /// Is object in a valid state?
        /// i.e., are all business rules satisfied?
        /// </summary>
        public virtual bool IsValid
        {
            get
            {
                return brokenRules.Count == 0;
            }
        }
        /// <summary>
        /// Diagnostics - lists broken rules.
        /// </summary>
        public virtual void DisplayBrokenRules()
        {
            ICollection keys = brokenRules.Keys;

            foreach (string key in keys)
            {
                Debug.WriteLine(key);
            }
        }

        #endregion

        #region Events

        public delegate void EventHandler(object sender, EventArgs e);

        /// <summary>
        /// A business rule is broken.
        /// </summary>
        public virtual event EventHandler OnInvalid;

        /// <summary>
        /// All business rules are satisfied.
        /// </summary>
        public virtual event EventHandler OnValid;

        #endregion // Events

        #region Protected interface

        /// <summary>
        /// If rule is broken, adds it to collection of broken rules,
        /// otherwise removes it.
        /// </summary>
        /// <param name="rule">Description of the business rule.</param>
        /// <param name="isBroken">Is the rule broken?</param>
        protected void RuleBroken(string rule, bool isBroken)
        {
            if (isBroken)
            {
                AddBrokenRule(rule);
            }
            else
            {
                RemoveBrokenRule(rule);
            }
        }

        /// <summary>
        /// Common wrapper for raising simple events,
        /// i.e., where no information is supplied in EventArgs.
        /// </summary>
        /// <param name="handler"></param>
        /// <param name="e"></param>
        protected virtual void RaiseEvent(EventHandler handler, EventArgs e)
        {
            if (handler != null)
            {
                handler(this, EventArgs.Empty);
            }
        }

        // Broken business rules
        protected Hashtable brokenRules;

        #endregion

        #region Implementation

        /// <summary>
        /// Adds broken rule to collection and notifies clients.
        /// </summary>
        /// <param name="rule">Description of the business rule.</param>
        private void AddBrokenRule(string rule)
        {
            bool isNewlyBroken =
                (brokenRules.ContainsKey(rule) == false);

            if (isNewlyBroken)
            {
                brokenRules.Add(rule, "");
                RaiseEvent(OnInvalid, EventArgs.Empty);
            }
        }

        /// <summary>
        /// Removes broken rule from collection.
        /// Notifies clients when there are
        /// no more broken rules.
        /// </summary>
        /// <param name="rule">Description of the business rule.</param>
        private void RemoveBrokenRule(string rule)
        {
            brokenRules.Remove(rule);

            if (brokenRules.Count == 0)
            {
                RaiseEvent(OnValid, EventArgs.Empty);
            }
        }
        #endregion // Implementation
    }
}

von der leite ich eine "kunden" klasse ab:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate.Collection.Generic;
using Iesi.Collections;
using System.Collections;

namespace NHibKunde.DBClasses
{
    public class kunde : BusinessObject
    {
        private int kunde_id;
        private string firma;
        private string email;
        private string vorname;
        private string nachname;
        private string telefon;
        private string kommentar;
        private System.Collections.Generic.IList<ansprechpartner> ansprechpartner;

        public virtual string Kommentar
        {
            get { return kommentar; }
            set { kommentar = value; }
        }

        public virtual string Telefon
        {
            get { return telefon; }
            set {
                    telefon = value;
                    RuleBroken("Telefon", telefon != "111");
                }
        }

        public virtual string Nachname
        {
            get { return nachname; }
            set { nachname = value; }
        }

        public virtual string Vorname
        {
            get { return vorname; }
            set { vorname = value; }
        }
        
        public virtual System.Collections.Generic.IList<ansprechpartner> Ansprechpartner
        {
            get {
                if (ansprechpartner == null)
                    ansprechpartner = new System.Collections.Generic.List<ansprechpartner>();
                    return ansprechpartner;                  
                }
            set { ansprechpartner = value; }
        }
        
        public virtual int Kunde_id
        {
            get { return kunde_id; }
            set { kunde_id = value; }

            
        }

        public virtual string Email
        {
            get { return email; }
            set { email = value; }
        }

        public virtual string Firma
        {
            get { return firma; }
            set { firma = value; }
        }



    }
}

Diese wir dann mit dem mapping file (hbm.xml) an die Datenbank gebunden :

<?xml version="1.0" encoding="utf-8" ?>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">

<class name="NHibKunde.DBClasses.kunde, NHibKunde" table="nhib.kunden">

&lt;id name=&quot;Kunde_id&quot; column=&quot;kunde_id&quot; unsaved-value=&quot;0&quot;&gt;  
  &lt;generator class=&quot;native&quot; /&gt;  
&lt;/id&gt;  
&lt;property name=&quot;Firma&quot; column=&quot;firma&quot;/&gt;  
&lt;property name=&quot;Email&quot; column=&quot;email&quot;/&gt;  
&lt;property name=&quot;Vorname&quot; column=&quot;vorname&quot;/&gt;  
&lt;property name=&quot;Nachname&quot; column=&quot;nachname&quot;/&gt;  
&lt;property name=&quot;Telefon&quot; column=&quot;telefon&quot;/&gt;  
&lt;property name=&quot;Kommentar&quot; column=&quot;kommentar&quot;/&gt;  

&lt;bag name=&quot;Ansprechpartner&quot; cascade=&quot;all-delete-orphan&quot; lazy=&quot;true&quot;&gt;  
  &lt;key column=&quot;kunde_fk&quot;/&gt;  
  &lt;one-to-many class=&quot;NHibKunde.DBClasses.ansprechpartner,NHibKunde&quot;/&gt;  
&lt;/bag&gt;  

</class>
</hibernate-mapping>

Funktioniert im Grunde genommen auch.

Eine sache funktioniert allerdings nicht!
Wenn ich wenn ich aus der Datenbank eine Klasse Kunde instanziere und die Telefonnummer in irgendwas anderes ändere als 111 sollte eigentlich zu brokenRules "Telefonummer" hinzugefügt und ein Event ausgelöst werden.

Wenn ich die Klasse direkt instanziere ohne sie aus der Datenbank zu befüllen geht es einwandfrei!

Jemand ne idee?

26.02.2008 - 14:42 Uhr

Hat sich erledigt.. mit " = new HashedSet()" kan mann es instanzieren!

26.02.2008 - 14:25 Uhr

hab grade gesehen das ich oben falsch gepostet hab. Ich verwende kein IList sondern ISet.

ISet lässt sich nicht instanzieren?!?! confused

26.02.2008 - 13:20 Uhr

verwendetes Datenbanksystem: Postgres

ich arbeite mich zur zeit etwas in NHibernate ein.

Habe mir folgende Klasse erstellt :


public class kunde
    {
        private int kunde_id;
        private string name;
        private string email;
        private IList ansprechpartner;

        public virtual IList Ansprechpartner
        {
            get { return ansprechpartner; }
            set { ansprechpartner = value; }
        }
        
        public virtual int Kunde_id
        {
            get { return kunde_id; }
            set { kunde_id = value; }
        }

        public virtual string Email
        {
            get { return email; }
            set { email = value; }
        }

        public virtual string Name
        {
            get { return name; }
            set { name = value; }
        }

Das Mapping zur Datenbank und die Referenz zur Ansprechpartner Klasse funktioniert. D.h ich kann einen Kunden aus der Datenbank holen. Der wird dann in das Objekt gespeichert. Es werden auch aus der anderen Tabelle die referenzierten ansprechpartner abgerufen und in "private IList ansprechpartner;" gespeichert.

Nun kann ich auch Ansprechpartner hinzufügen un löschen.

Wenn ich jetzt jedoch einen neuen Kunden erstellen will indem ich die Klasse instanziere, kann ich keine Ansprechpartner hinzufügen :

Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.

Warum ist dass so? stehe total auf dem Schlauch!

15.02.2008 - 12:50 Uhr

Hi@all,

kann mir jemand etwas zu den .Net Remoting services erzählen? =)

Bei Wikipedia steht folgende Aussage :

Die verschiedenen Strukturen innerhalb von .NET 2.0 sind trotz breiter Auswahl und technisch teilweise guter Ansätze, nicht ausgereift. Insbesondere die .NET Remoting Services sollten nur dann eingesetzt werden, wenn man über ihre Schwächen und Einschränkungen genau Bescheid weiß. In Bezug auf Web Services bietet .NET jedoch eine der technisch führenden Implementierungen an.

Was sind den die Schwächen und Einschränkungen? Gibts da irgendwo was zu lesen?

Sind die Web Services das "gleiche" nur besser? Wenn ich das richtig verstehe basieren die .Net Web Services auf dem IIS?!?! Und .Net Remoting ist dann in der Anwendung ein "Eigener Server"???

14.02.2008 - 14:52 Uhr

naja... belassen wir es mal dabei...

ich hatte eigentlich gehofft, dass jemand mal über meinen geposteten Quelltext schaut der ein bisschen mehr Ahnung hat wie ich.... vieleicht findet sich ja noch jemand..

es mir ja nicht darum ob man es irgendwie auf nem anderen weg Lösen kann.. sondern ob der weg den ich gewählt habe akzeptabel umgestzt ist.

14.02.2008 - 14:30 Uhr

Hallo herbivore....

mein Anliegen ist eigentlich nicht mehr eine Lösung zu finden. Desswegen hatte ich auch einen neuen Thread erstellt. Ich vermute mal dass du ihn hier reinverschoben hast?!?!

Ich möchte eigentlich schon gerne an meiner Lösung festhalten da sie sehr gut funktioniert für meine Zwecke... was ich eigentlich gerne wissen wollte ist was ihr von meiner Umsetzung haltet. Klar gibt es mehrere Wege nach Rom. Ich habe EINEN möglichen gefunden, bin mir aber mit der Umsetzung nicht ganz sicher.

Ich denke in einem neuen Thread wären solche Missverständnisse nicht aufgetreten!!!!

13.02.2008 - 19:28 Uhr

entweder ich steh komplett auf dem schlauch =)

oder du hast nicht gesehen was ich oben bereits gebastelt hab

oder wir reden aneinander vorbei?!?! =)

Hab ja schon eine "Lösung" gefunden... wollte nur mal nach Meinungen fragen.

So wie ich dich jetzt verstehe wäre dein Vorschlag eine ANDERE Lösung?

13.02.2008 - 19:18 Uhr

Naja, eigenen Compiler bauen will ich nich wirklich! Ich möchte den IronPython Compiler Benutzen... siehst du ja auch in meinem CodeSchnippsel weiter oben!

13.02.2008 - 18:41 Uhr

hi Kartoffel,

danke für deine Antwort. Ich bin mir aber nicht ganz schlüssig ob mich deine Anmerkung weiterbringt!

Ich möchte keinen eigenen Compiler bauen! Ich möchte schon gerne die von mir gennante Methode mit IronPython benutzen!

Oder verstehe ich dich falsch?

13.02.2008 - 12:12 Uhr

Hallo,

ich bin gerade dabei eine Komponente zu entwickeln, die aus einer Formel die in einem String gespeichert ist ein Ergebnis berechnet.

Da ich noch ziemlicher Anfänger bin wollte ich hier mal nachfragen was ihr davon haltet.

  • Habe ich irgendwelche Anfängerfehler gemacht?
  • Wie mache ich die Ereignisbehandlung? Muss ich alle Exceptions die bei pe.Evaluate auftreten können einzeln abfangen? Oder leitet man dass irgendwie an die Aufrufende Anwendung weiter?
  • Was haltet ihr generell von der Idee?
  • Hat jemand ne Idee wie ich folgendes verhindern kann : Wenn in der Formel z.B. sqrt benutzt wird und ein Benutzer fügt "s" als Variable hinzu, würde er auch das "s" aus "sqrt" ersetzen. Hab im Moment keine Idee wie ich das Verhindern kann!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IronPython.Hosting;
using System.Text.RegularExpressions;
using IronPython.Runtime.Exceptions;

namespace PythonRechner
{
    public class Rechner
    {
        public Rechner()
        {
            this.pe.Execute("from IronPython.Modules.PythonMath import *");
        }
        
        private PythonEngine pe = new PythonEngine();
        public List<variable> variablen = new List<variable>();

        private string formel;
        public string Formel
        {
            get { return formel; }
            set { formel = value; }
        }
        
        public void addVariable(variable var)
        {
            variablen.Add(var);
        }

        public double CalcToDouble()
        {
            string werte_formel = formel;
            double ergebnis = 0;
            
            foreach (variable temp_variable in variablen)
            {
                werte_formel = Regex.Replace(werte_formel, temp_variable.Name, temp_variable.Wert.ToString());
                
            }

            werte_formel = Regex.Replace(werte_formel, ",", ".");

           
            ergebnis = Convert.ToDouble(pe.Evaluate(werte_formel));
            
            return ergebnis;
        }

        public string CalcToString()
        {
            string werte_formel = formel;
            string ergebnis = "";

            foreach (variable temp_variable in variablen)
            {
                werte_formel = Regex.Replace(werte_formel, temp_variable.Name, temp_variable.Wert.ToString());
            }

            werte_formel = Regex.Replace(werte_formel, ",", ".");


            ergebnis = pe.Evaluate(werte_formel).ToString();

            return ergebnis;
        }

    }

    public class variable
    {
        public variable(string name, double wert)
        {
            this.name = name;
            this.wert = wert;
        }
        
        private string name;
        private double wert;

        public double Wert
        {
            get { return wert; }
            set { wert = value; }
        }

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        
        
    }
}

funktionieren tut das Ganze so :


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PythonRechner;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Rechner pr = new Rechner();
            pr.Formel = "a*b*c*sqrt(c)";

            pr.addVariable(new variable("a",27.123));
            pr.addVariable(new variable("b",27.123));
            pr.addVariable(new variable("c",27.123));

            Console.WriteLine(pr.CalcToDouble().ToString());

            Console.ReadLine();
        }
    }
}

11.02.2008 - 20:16 Uhr

verwendetes Datenbanksystem: Postgres

Hallo an alle Profis,

ich bin etwas verwirrt was Datenbankzugriffe angeht, und wollte mal fragen wie es in der Programmierwelt so aussieht.

Hab mich schon etwas mit Postgres und Npgsql auseinandergesetzt und auch schon ein Paar kleine Programme geschrieben die Datenbanken auslesen und beschreiben können. Mit Connections, Dataadapter, Datatable bzw Dataset und Bindung an die GUI.

Hab jetzt schon des öffteren von O/R Mappern gelesen und wenn ich es richtig verstehe wird durch einen O/R Mapper die Datenbankstruktur in Klassen abgebildet. Und wenn ich weiter richtig verstehe macht ein O/R Mapper einem die Arbeit einfach nur leichter?!? Mann könnte ja in einem Programm das O/R Mapping auch selbst in die Hand nehmen?!?

Hab auch nach EINIGEN startschwierigkeiten NHibernate mit dem Beispielprojekt aus der Doku ans laufen gebracht. Muss aber ehlrich sagen das mir NHibernate überhaupt nicht gefällt weil ich keine wirklich gute Doku gefunden hab. Oder hab ich nur falsch gesucht?!

Gibt es etwas vergleichbares wie NHibernate für .Net? Etwas zu dem viele Tutorials/Howtos/Doku vorhanden ist?

Was mich auch schon lange beschäftigt : Ist es Praktikabel auch für größere Projekte mit vielen Clients die Datenbank direkt anzusprechen? Oder nimmt man dann ne eigene Serveranwendung die das O/R-Mapping übernimmt?

Naja ich glaub ich lass mal gut sein jetzt. Hab die Befürchtung dass wenn ich zu viel schreibe sich niemand mehr die Zeit nimmt alles zu lesen =)

Vieleicht will ja jemand mal seinen qualifizierten Senf dazu abgeben ^^. Würd mich freuen.