myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
   » Plugin für Firefox
   » Plugin für IE7
   » Gadget für Vista
» Regeln
» Wie poste ich richtig?
» Datenschutzerklärung
» wbb-FAQ

Mitglieder
» Liste / Suche
» Stadt / Anleitung dazu
» Wer ist wo online?

Angebote
» ASP.NET Webspace
» Bücher
» Zeitschriften
   » dot.net magazin
» Accessoires

Ressourcen
» .NET-Glossar
» guide to C#
» openbook: Visual C#
» openbook: OO
» .NET BlogBook
» MSDN Webcasts
» dotnetjob.de
» Search.Net

Team
» Kontakt
» Übersicht
» Wir über uns
» Bankverbindung
» Impressum

» Unsere MiniCity
MiniCity
» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » Rund um die Programmierung » Mehrmandantenfähige Anwendung + verschiedene Datenbanken + WCF Service
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | An Freund senden | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Mehrmandantenfähige Anwendung + verschiedene Datenbanken + WCF Service

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
Campy Campy ist männlich
myCSharp.de-Mitglied

Dabei seit: 02.04.2008
Beiträge: 319


Campy ist offline

Mehrmandantenfähige Anwendung + verschiedene Datenbanken + WCF Service

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo zusammen,

meine bestehende Anwendung kommunziert momentan direkt mit der Datenbank, sprich der DL und Bl sind mit dem UI Layer in der gleichen Anwendung.

Folgendermaßen ist meine Anwendung zur Zeit aufgebaut:
Datalayer:
- Methoden für den MSSQL Server

DomainModel
- Businessobjekte
- Interfaces für die Repositories

BusinessLayer
- Implementation der Repository Interfaces + Logik

Programm
- GUI (Windows Forms)

Beim Start meiner Anwendung werden alle Repositories mit dem vorher ausgewählten ConnectionString initialisiert (so wurde bis jetzt die mehrmandantenfähigkeit implementiert -> Jeder Mandant hat seine eigene Datenbank).

In der nächsten Version sollen die ersten 3 Projekte ausgelagert werden -> WCF Service. Allerdings möchte ich, wenn möglich das Mandantenschema so beibehalten wie es jetzt ist.

Meine Frage ist nun, was kann ich in der nächsten Version in Hinsicht auf das Applikationsdesign verbessern und wie implementiere ich die mehrmandantenfähigkeit mit mehreren Datenbanken. Sollte ich hierzu eine weitere Schicht einbauen die das ganze kapselt, wenn ja, wie setze ich das am bestem um.

Vielen Dank!
Neuer Beitrag 24.01.2011 15:53 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
herbivore
myCSharp.de-Team (Admin)

images/avatars/avatar-2627.gif


Dabei seit: 11.01.2005
Beiträge: 47.492
Entwicklungsumgebung: csc/nmake (nothing is faster)
Herkunft: Berlin


herbivore ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Campy,

ich sehe das Problem noch nicht. Nur weil deine Anwendung in Zukunft verteilt laufen soll, musst du doch nichts an der Mandantenfähigkeit ändern.

herbivore
Neuer Beitrag 24.01.2011 19:37 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Campy Campy ist männlich
myCSharp.de-Mitglied

Dabei seit: 02.04.2008
Beiträge: 319

Themenstarter Thema begonnen von Campy

Campy ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo herbivore,

ich glaube ich hatte einen Denkfehler, ich werd heute mal ne kleine Testapplikation schreiben und schauen auf welche Probleme ich evtl. stoße.
Sorry, dass ich das nicht vorher gemacht hatte :(
Neuer Beitrag 24.01.2011 20:35 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Xynratron
myCSharp.de-Mitglied

Dabei seit: 24.09.2006
Beiträge: 1.174
Entwicklungsumgebung: VS 2005 - 2010


Xynratron ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Campy,

ich denke, du missverstehst herbivore (oder ich mache es): auch mit WCF kannst du natürlich mehrere Datenbanken verwenden und so das aktuelle Schema praktisch komplett beibehalten. Du musst dich nicht sofort entschuldigen^^

Habt ihr bis jetzt die Mandantenfähigkeit nur über den Connectionstring unterschieden? Natürlich kann man das auch weiterhin machen, aber nen Connectionstring über WCF zu übertragen wäre etwas gewagt. Ich würde es anhand eines Logins (im WCF abzuhandeln) regeln und da dann den Connectionstring aus einer Konfig-Datei oder Datenbank auslesen/zusammenbauen.

Der Ansatz der unterschiedlichen Layer (den Du hast) lädt ja auch geradezu ein, noch nen Layer (WCF) dazwischen zu bauen.

:-)

Xynratron
Neuer Beitrag 24.01.2011 21:03 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Campy Campy ist männlich
myCSharp.de-Mitglied

Dabei seit: 02.04.2008
Beiträge: 319

Themenstarter Thema begonnen von Campy

Campy ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von Xynratron:
ich denke, du missverstehst herbivore (oder ich mache es): auch mit WCF kannst du natürlich mehrere Datenbanken verwenden und so das aktuelle Schema praktisch komplett beibehalten. Du musst dich nicht sofort entschuldigen^^

Alles klar :)

Zitat von Xynratron:
Habt ihr bis jetzt die Mandantenfähigkeit nur über den Connectionstring unterschieden? Natürlich kann man das auch weiterhin machen, aber nen Connectionstring über WCF zu übertragen wäre etwas gewagt. Ich würde es anhand eines Logins (im WCF abzuhandeln) regeln und da dann den Connectionstring aus einer Konfig-Datei oder Datenbank auslesen/zusammenbauen.

Jep genau das wurde bis jetzt gemacht, der Connectionstring war/ist natürlich verschlüsselt in der app.config gespeichert. Für die Authentifizierung kann ich mir ja nen eigenen Membership Provider schreiben der die Anmeldung erledigt. Aber ich schließe ja nach jeder Operation die Verbindung zum Service und ich möchte den Mandanten ja nur beim ersten Login setzen, wie also mache ich es, dass der Service trotzdem weiß, mit welchem Mandanten ich verbunden bin und welche Rechte dieser User besitzt. Momentan ist meine Rechteverwaltung ein Singleton Objekt der eine List<Permission> hat +  mycsharp Thread. Evtl. ist das auch garkein Problem, mein WCF Buch ist erst heute angekommen ..

Zitat von Xynratron:
Der Ansatz der unterschiedlichen Layer (den Du hast) lädt ja auch geradezu ein, noch nen Layer (WCF) dazwischen zu bauen.

Genau das hab ich mir auch gedacht, deswegen auch die entscheidung die ganze BL und den DL vom Programm selber wegzunehmen.

Hoffe mir kann noch jemand von Euch bei den oben genannten Problem(en) helfen. Danke!

Dieser Beitrag wurde 4 mal editiert, zum letzten Mal von Campy am 24.01.2011 22:44.

Neuer Beitrag 24.01.2011 21:15 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Rainbird Rainbird ist männlich
myCSharp.de-Poweruser/ Experte

images/avatars/avatar-2834.jpg


Dabei seit: 28.05.2005
Beiträge: 3.716
Entwicklungsumgebung: Visual Studio 2010
Herkunft: Mauer


Rainbird ist offline MSN-Passport-Profil von Rainbird anzeigen

Sitzung

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Campy,

was Du brauchst ist eine Sitzungsverwaltung. Wenn ein Client sich erfolgreich angemeldet hat, sollte auf dem Server eine Sitzung erzeugt werden, welche die Identität des Client-Benutzers und seine Sitzungseinstellungen (z.B. an welchem Mandanten angemeldet) speichert. Du brauchst den Client dann nicht jedes Mal zu authentifizieren und die Einstellungen für jeden Funktionsaufruf mitgeben.

Leider kann WCF das standardmäßig nicht. Unter Sitzung wird in WCF was anderes verstanden. Man kann das zwar selber in WCF nachrüsten. Dazu muss man sich aber intensiv mit den Eingeweiden von WCF auseinandersetzen und eine eigene Erweiterung (Behavor) schreiben. Wenn Dein Szenario nicht zu komplex ist, kannst Du die Sitzungsgeschichte über den  OperationContext abbilden. Glücklich wirst Du aber auf lange Sicht damit nicht werden.

Interessanter sind da schon folgende Links:
 MSDN: WCF Extensible Objects
 MSDN: Configuring and Extending WCF with Behaviors

Wenn es nicht unbedingt WCF sein muss und Deine Anwendung auch nicht interoperabel sein muss, dann könnte  Zyan für Dich interessant sein. Zyan bringt eine fertige Sitzungsverwaltung inklusive Unterstützung für Sitzungsvariablen mit. Hier findest Du ein Kleines Anwendungsbeispiel für Zyan:  Zyan Dokumentation: Erste Schritte
Neuer Beitrag 25.01.2011 07:54 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Campy Campy ist männlich
myCSharp.de-Mitglied

Dabei seit: 02.04.2008
Beiträge: 319

Themenstarter Thema begonnen von Campy

Campy ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von Rainbird:
Leider kann WCF das standardmäßig nicht. Unter Sitzung wird in WCF was anderes verstanden. Man kann das zwar selber in WCF nachrüsten. Dazu muss man sich aber intensiv mit den Eingeweiden von WCF auseinandersetzen und eine eigene Erweiterung (Behavor) schreiben. Wenn Dein Szenario nicht zu komplex ist, kannst Du die Sitzungsgeschichte über den  OperationContext abbilden. Glücklich wirst Du aber auf lange Sicht damit nicht werden.

Interessanter sind da schon folgende Links:
 MSDN: WCF Extensible Objects
 MSDN: Configuring and Extending WCF with Behaviors

Dann werd ich um diesen Weg wohl nicht herumkommen, lieber einmal richtig als später nochmal neu ;). Als "Sessionprovider" verwende ich wohl am besten gleich die Datenbank oder?

Zitat von Rainbird:
Wenn es nicht unbedingt WCF sein muss und Deine Anwendung auch nicht interoperabel sein muss, dann könnte  Zyan für Dich interessant sein. Zyan bringt eine fertige Sitzungsverwaltung inklusive Unterstützung für Sitzungsvariablen mit. Hier findest Du ein Kleines Anwendungsbeispiel für Zyan:  Zyan Dokumentation: Erste Schritte

Kommt leider für meinen Anwendungsfall nicht in Frage.

Vielen Dank!!!

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Campy am 25.01.2011 08:19.

Neuer Beitrag 25.01.2011 08:16 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Rainbird Rainbird ist männlich
myCSharp.de-Poweruser/ Experte

images/avatars/avatar-2834.jpg


Dabei seit: 28.05.2005
Beiträge: 3.716
Entwicklungsumgebung: Visual Studio 2010
Herkunft: Mauer


Rainbird ist offline MSN-Passport-Profil von Rainbird anzeigen

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Campy,

Zitat von Campy:
Als "Sessionprovider" verwende ich wohl am besten gleich die Datenbank oder?

Das kommt auf die vorraussichtliche Größe Deines Projekts an. Wenn die Software für nur wenige (1-50) gleichzeitige Benutzer ausgelegt werden muss/soll und der Betrieb des Applikationsservers in einem Cluster nicht in Frage kommt, bist Du mit einem In-Memory-Sessionprovider schneller und unkomplizierter unterwegs.

Für alle anderen Anwendungsfälle unbedingt die Sitzungen in einer DB (z.B. SQL Server) verwalten. Das macht die Anwendung wesentlich skalierbarer und versperrt auch nicht den Weg für einen Einsatz im Cluster. Wenn Datenbankserver und SQL Server im selben Backbone-Netz sind, werden die kurzen Zugriffe auf die Sitzungstabellen verschmerzbar sein.

Im Zweifelsfall größer Denken, denn wer weiß, wie viele User die Anwendung in fünf Jahren bedienen muss.
Neuer Beitrag 25.01.2011 09:23 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Campy Campy ist männlich
myCSharp.de-Mitglied

Dabei seit: 02.04.2008
Beiträge: 319

Themenstarter Thema begonnen von Campy

Campy ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Rainbird,

ich werd auf jeden Fall die Datenbank dafür verwenden.
Das einzige Problem, das ich noch sehe ist, wann schmeiße ich eine Session raus?
Ich mein, wenn er sich abmeldet / das Programm schließt ist das ja kein Problem. Aber was wenn der PC einfach ausgeschaltet wird.
Wenn ich das noch irgendwie erkennen kann, dann könnte man darauf auch die Lizenz mit concurrent Usern aufbauen.

Gibt es eine andere Möglichkeit als nach z.B.: 15 Minuten inaktivität die Session zu kicken? Falls nein, könnte ich die Anwendung ja immer im zuletzt geöffneten Mandanten öffnen und einen "Mandanten wechseln" Dialog implementieren...
Neuer Beitrag 25.01.2011 10:24 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
mg.net
myCSharp.de-Mitglied

Dabei seit: 08.01.2010
Beiträge: 153


mg.net ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Es gibt bei dieser Sache natürlich einen ganz praktischen Aspekt: Die Mandantenauswahl erfolgt i.d.R. im Client und muss sich durch alle Services durchziehen, die sich wiederum gegenseitig verwenden.

Die Auswahl eines Mandanten hat verschiedene Auswirkungen. Die wichtigste Auswirkung ist wahrscheinlich bei Deinem Projekt der Connection-String, aber in vielen Anwendungen gibt es noch weitere: Zum Beispiel die verwendeten Berichte oder Beleglayouts oder Rechenregeln.

Das so ziemlich dümmste was passieren könnte ist, wenn durch Fehlkonfigurationen Daten kreuz und quer geschrieben würden.

Von Sessions, jedweder Art, rate ich dringend ab. Falsch umgesetzt wird daraus schnell ein Strick.

Eine Möglichkeit der Mandantentrennung ist zum Beispiel die Unterscheidung im Hosting. Kommt der IIS zum Einsatz könnte für jeden Mandant ein Application Pool mit eigener Identität zum Einsatz kommen. Die Rechte könnten dann konsistent durchgezogen werden, so dass ein Client indirekt über die Services nur in die Datenbank schreiben könnte, die dem jeweiligen Mandant entspricht. Ein weiterer Vorteil ist die Isolation der einzelnen Mandanten im Hosting-Prozess.

Eleganter geht das aber über eine Custom Extension, wie schon angedeutet. Das kann zum Beispiel so gelöst werden, dass an jeden Message Header Zusatzinformationen angehängt werden, in Deinem Beispiel der ausgewählte Mandant (oder Connection String). Außerdem kann so auch gleich der Host und der angemeldete Benutzer übertragen werden, für den Fall, dass man ihn später zu Protokollierzwecken in die Datenbank schreiben möchte.

Wir haben so etwas seit Jahren im Einsatz. Wenn Du möchstest, dann schicke ich Dir den Quellcode und eine kurze Anleitung zu.

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von mg.net am 25.01.2011 10:38.

Neuer Beitrag 25.01.2011 10:35 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Campy Campy ist männlich
myCSharp.de-Mitglied

Dabei seit: 02.04.2008
Beiträge: 319

Themenstarter Thema begonnen von Campy

Campy ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo mg.net

gerne würde ich mir mal deine Lösung anschauen.
Willst du den Quellcode am liebsten per Email versenden?

Danke!
Neuer Beitrag 25.01.2011 10:50 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
mg.net
myCSharp.de-Mitglied

Dabei seit: 08.01.2010
Beiträge: 153


mg.net ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ja, bitte. Wie lautet die E-Mail.


mycsharp.de  Moderationshinweis von winSharp93 (25.01.2011 18:05):

Du kannst deinen Code auch gerne in  .NET-Komponenten und C#-Snippets veröffentlichen - dann steht sie auch anderen Lesern dieses Threads zur Verfügung.
 
Neuer Beitrag 25.01.2011 11:43 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Rainbird Rainbird ist männlich
myCSharp.de-Poweruser/ Experte

images/avatars/avatar-2834.jpg


Dabei seit: 28.05.2005
Beiträge: 3.716
Entwicklungsumgebung: Visual Studio 2010
Herkunft: Mauer


Rainbird ist offline MSN-Passport-Profil von Rainbird anzeigen

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von mg.net:
Von Sessions, jedweder Art, rate ich dringend ab. Falsch umgesetzt wird daraus schnell ein Strick.

Klar, man muss die Sitzungsverwaltung schon sauber implementieren. Vor allem sollte das Handling der Sitzungungen transparent und unter der Haube passieren. Dann kann auch nichts schief gehen.

Zitat von mg.net:
Kommt der IIS zum Einsatz könnte für jeden Mandant ein Application Pool mit eigener Identität zum Einsatz kommen. Die Rechte könnten dann konsistent durchgezogen werden, so dass ein Client indirekt über die Services nur in die Datenbank schreiben könnte, die dem jeweiligen Mandant entspricht.

Ein Nachteil dieser Methode ist der erhöhte Deployment- und Konfigurationsaufwand. Es muss dann für jeden Mandant eine separate Kopie der Serveranwendung ausgerollt und gepflegt werden. Außerdem ist jede Mandanteninstanz dann über einen anderen URL / Port erreichbar. Das muss ich im Client wieder in der Konfiguration verwalten.

Zitat:
Ein weiterer Vorteil ist die Isolation der einzelnen Mandanten im Hosting-Prozess.

Dazu muss man nicht für jeden Mandanten eine eigene Kopie der Serveranwendung hosten. Eigentlich ist es sogar einfacher, alle Mandanten in einer SQL Server Datenbank zu verwalten. Für jeden Mandant wird ein Schema erstellt. Für jeden Mandanten wird ein separates SQL Login erstellt, welches nur Zugriffsrechte auf die Tabellen im Schema des entsprechenden Mandanten hat. Für Stammdaten, die mandantenübergreifend genutzt werden (Devisenkurse, Postleizahlen, Ländertabellen etc.) gibt es ein Stammdatenschema, auf das alle Mandanten SQL Logins Zugriff haben. Das hällt die SQL Datenbank schlank, isoliert die Mandantendaten aber trotzdem sicherheitstechnisch hervorragend.

So brauche ich weder verschiedene Connection Strings, noch mehrfaches Ausrollen der Lösung. Der Client muss nur beim Anmeldevorgang am Applikationsserver angeben, für welchen Mandanten er sich anmeldet. Damit er das nicht bei jeder entfernten Methode als Parameter mitgeben muss, braucht es eine Sitzungsverwaltung.

Es sollte vermieden werden, alles das was eigentlich in einer Sitzung gehalten werden sollte (Benutzeridentität, Mandantenschlüssel, usw.) bei jedem entfernten Methodenaufruf in Headern zwischen Client und Server ausgetauscht wird. Das ist unnötiger Overhead, der sich Nachteilig auf die Performanz auswirkt. Ein eindeutiger Sitzungsschlüssel (vorzeugsweise eine Guid, da man die nicht erraten kann) genügt.

Der Knackpunkt ist, wie dieser Sitzungsschlüssel - ohne viel Aufsehen und ohne ihn immer irgendwie in die Hand nehmen zu müssen - vom Client zum Server (und von dort ggf. auf weitere Server) gelangt. In .NET Remoting ist das kinderlicht. Da gibt es den sogenannten Aufrufkontext (CallContext). Dort packt man den Schlüssel auf der Clientseite rein und er wird automatisch über die gesamte Aufrufkette an alle Kommunikationsteilnehmer implizit übertragen. Auf dem Server kann man den Schlüssel einfach wieder aus dem CallContext rausholen.
In WCF gibt es keinen CallContext. Man muss sich sowas also selber bauen. Also eine WCF-Erweiterung, die den aktuellen Sitzungsschlüssel am Client aus einer statischen (oder threadstatischen) Variable liest und ihn als Transportheader an die zu versendende WCF-Nachricht anhängt. Serverseitig wird ebenfalls eine Erweiterung benötigt, die vor dem Dispatchen der Nachricht den Sitzungsschlüssel aus dem entsprechenden Header liest und in einer threadstatischen Variable (oder in einem Slot des Threadspeichers; ist aber langsamer als eine threadstatische Variable) ablegt. Der Dienstaufruf kann den Sitzungsschlüssel des Aufrufers dann einfach jederzeit aus der threadstatischen Variable lesen. Da jeder Dienstaufruf in einem eigenen Thread abgearbeitet wird, gibt es auch keine Probleme wenn Benutzer A die Dienstmethode GetInvoice für Mandant 1 und Benutzer B für Mandant 2 aufruft. Die Sitzung und damit die Mandanteninformation wird von der Kommunikationsinfrastruktur an den jeweiligen Arbeitsthread "gehängt".

Mit diesem Ansatz habe ich sehr gute Erfahrungen gemacht.

Natürlich kann man Mandanten auch über getrenntes Hosting und getrennte Datenbanken abbilden. Das ist ja nicht falsch und die naheliegendste Lösung. Erfahrungsgemäß verursacht dies aber höhere Betriebskosten.
Neuer Beitrag 26.01.2011 08:11 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Campy Campy ist männlich
myCSharp.de-Mitglied

Dabei seit: 02.04.2008
Beiträge: 319

Themenstarter Thema begonnen von Campy

Campy ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Rainbird,

das mit einer Datenbank hab ich mir auch schon überlegt. Das Problem mit dem Übertragen des monentanigen Mandanten schaffe ich damit zwar nicht aus der Welt aber das mit den Mandantenunabhängigen Tabellen (Plz, evtl Userverwaltung, etc.) hat natürlich schon auch seine Vorteile, das Würde heißen, ich lege für jeden Mandanten die Struktur an und erzeuge alle DB Objekte(Tabellen Stored Procedures) mit einem Präfix z.B.: [Mandantenname]$[Objektname] und ich muss dann bei den Proc aufrufen nur noch den Präfix ranhängen. Da alle DB-Operationen über Stored Procedures ausgeführt werden muss ich ja nur beim Erzeugen dieser die Selects anpassen, was ja auch kein Problem ist. Ich werde das mal ins Auge fassen.

Das mit der Erweiterung für WCF gefällt mir allerdings schon sehr gut und ich denke ich werde das in Kombination mit einer DB so umsetzen.

Danke für Eure Hilfe!
Neuer Beitrag 26.01.2011 13:07 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Rainbird Rainbird ist männlich
myCSharp.de-Poweruser/ Experte

images/avatars/avatar-2834.jpg


Dabei seit: 28.05.2005
Beiträge: 3.716
Entwicklungsumgebung: Visual Studio 2010
Herkunft: Mauer


Rainbird ist offline MSN-Passport-Profil von Rainbird anzeigen

Schema

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von Campy:
... das Würde heißen, ich lege für jeden Mandanten die Struktur an und erzeuge alle DB Objekte(Tabellen Stored Procedures) mit einem Präfix z.B.: [Mandantenname]$[Objektname] und ich muss dann bei den Proc aufrufen nur noch den Präfix ranhängen. Da alle DB-Operationen über Stored Procedures ausgeführt werden muss ich ja nur beim Erzeugen dieser die Selects anpassen, was ja auch kein Problem ist. Ich werde das mal ins Auge fassen.

Kein Präfix vor die Tabellennamen machen!
Ich spreche von SQL Server Sechemas. So wie dbo.Tabelle (dbo ist das Standardschema des Database Owners) kannst Du auch eigene Schemas definieren, wie z.B. Mandant1.Angebote und Mandant2.Angebote. Auf Schemas kannst Du separat Zugriffsrechte vergeben.

Siehe  Berechtigungshierarchie (Datenbankmodul)

Der SQL Server kann also Tabellen verschiedener Mandanten standardmäßig voneinander isolieren.
Neuer Beitrag 26.01.2011 16:20 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Campy Campy ist männlich
myCSharp.de-Mitglied

Dabei seit: 02.04.2008
Beiträge: 319

Themenstarter Thema begonnen von Campy

Campy ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ahh alles klar, mit den SQL Schemas bin ich vertraut, da hab ich wohl in die falsche Richtung gedacht! Vielen Dank!
Neuer Beitrag 26.01.2011 18:29 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Zwischen diesen beiden Beiträgen liegt mehr als ein Jahr.
Campy Campy ist männlich
myCSharp.de-Mitglied

Dabei seit: 02.04.2008
Beiträge: 319

Themenstarter Thema begonnen von Campy

Campy ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von Rainbird:
Ich spreche von SQL Server Sechemas. So wie dbo.Tabelle (dbo ist das Standardschema des Database Owners) kannst Du auch eigene Schemas definieren, wie z.B. Mandant1.Angebote und Mandant2.Angebote. Auf Schemas kannst Du separat Zugriffsrechte vergeben.

Siehe  Berechtigungshierarchie (Datenbankmodul)

Der SQL Server kann also Tabellen verschiedener Mandanten standardmäßig voneinander isolieren.

Hallo,

funktioniert das auch noch mit dem Entity Framework ?

MFG Campy
Neuer Beitrag 03.05.2012 12:06 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
gfoidl gfoidl ist männlich
myCSharp.de-Team (Moderation)

images/avatars/avatar-2894.jpg


Dabei seit: 07.06.2009
Beiträge: 5.358
Entwicklungsumgebung: VS 2010 sup{Editionen}
Herkunft: Waidring / Tirol


gfoidl ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Campy,

ab EF 4.1 gehts mit dem Fluent Api für die Konfiguration recht einfach. Siehe hierzu  EF Feature CTP5: Fluent API Samples (die Methode ToTable wäre es).

Sonst kann auch das  Entity Framework Runtime Model Adapter hierfür verwendet werden.


mfG Gü
Neuer Beitrag 03.05.2012 12:15 Beiträge des Benutzers | zu Buddylist hinzufügen
Campy Campy ist männlich
myCSharp.de-Mitglied

Dabei seit: 02.04.2008
Beiträge: 319

Themenstarter Thema begonnen von Campy

Campy ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo gfoidl,

Zitat:
ab EF 4.1 gehts mit dem Fluent Api für die Konfiguration recht einfach. Siehe hierzu EF Feature CTP5: Fluent API Samples (die Methode ToTable wäre es).

soweit ich das sehe, bringt mir das aber nur bei CodeFirst etwas?

Zitat:
Sonst kann auch das Entity Framework Runtime Model Adapter hierfür verwendet werden.

Das sollte auch ohne CodeFirst funktionieren oder? Hast du das schon einmal verwendet ?

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Campy am 03.05.2012 12:21.

Neuer Beitrag 03.05.2012 12:18 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
gfoidl gfoidl ist männlich
myCSharp.de-Team (Moderation)

images/avatars/avatar-2894.jpg


Dabei seit: 07.06.2009
Beiträge: 5.358
Entwicklungsumgebung: VS 2010 sup{Editionen}
Herkunft: Waidring / Tirol


gfoidl ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Campy,

3x ja.

mfG Gü
Neuer Beitrag 03.05.2012 13:34 Beiträge des Benutzers | zu Buddylist hinzufügen
Campy Campy ist männlich
myCSharp.de-Mitglied

Dabei seit: 02.04.2008
Beiträge: 319

Themenstarter Thema begonnen von Campy

Campy ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich überlege gerade nur noch, ob ich das ganze mit Prefix oder mit Schemas machen soll ..

- Mandantenübergreifende Tabellen => Kein Schema (dbo) oder Prefix
- Mandantentabellen => Schema oder Prefix

Dann 2 RepositoryBase klassen für beide Fälle..
Neuer Beitrag 03.05.2012 13:52 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
gfoidl gfoidl ist männlich
myCSharp.de-Team (Moderation)

images/avatars/avatar-2894.jpg


Dabei seit: 07.06.2009
Beiträge: 5.358
Entwicklungsumgebung: VS 2010 sup{Editionen}
Herkunft: Waidring / Tirol


gfoidl ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Campy,

beim SQL Server würde ich ganz klar Schemas verwenden. Diese sind dafür gedacht und die Rechteverwaltung (Logins) lässt sich damit einfach umsetzen.


mfG Gü
Neuer Beitrag 03.05.2012 14:06 Beiträge des Benutzers | zu Buddylist hinzufügen
Campy Campy ist männlich
myCSharp.de-Mitglied

Dabei seit: 02.04.2008
Beiträge: 319

Themenstarter Thema begonnen von Campy

Campy ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich kriege sofort ne NullReferenceException bei meinem Test mit dem PrefixAdapter..

C#-Code:
public partial class SKSERPEntities : AdaptingObjectContext
    {


    public SKSEntities(string connectionString, string Prefix)
            : base(connectionString, new ConnectionAdapter(
                new TablePrefixModelAdapter(Prefix),
                System.Reflection.Assembly.GetCallingAssembly()))
        {
            this.ContextOptions.LazyLoadingEnabled = true;
            OnContextCreated();
        }

Mach ich was falsch?

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Campy am 03.05.2012 15:22.

Neuer Beitrag 03.05.2012 15:21 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Campy Campy ist männlich
myCSharp.de-Mitglied

Dabei seit: 02.04.2008
Beiträge: 319

Themenstarter Thema begonnen von Campy

Campy ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ok, den obigen Fehler hab ich gestern noch gefunden.

Da mein edmx File in einem anderen Assembly liegt musste ich

C#-Code:
System.Reflection.Assembly.GetCallingAssembly()))

durch

C#-Code:
System.Reflection.Assembly.GetAssembly(...)))

ersetzen.

Jetzt bekomme ich aber für jede Tabelle folgenden Fehler:

Fehlermeldung:
(0,0) : error 2007: The Table 'SKS$Tabelle' specified as part of this MSL does not exist in MetadataWorkspace.
(0,0) : error 2063: At least one property must be mapped in the set mapping for 'Tabelle'.
Neuer Beitrag 04.05.2012 10:07 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Campy Campy ist männlich
myCSharp.de-Mitglied

Dabei seit: 02.04.2008
Beiträge: 319

Themenstarter Thema begonnen von Campy

Campy ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Genau das ist mein Fehler:
 System.Data.MappingException: Schema specified is not valid

EDIT:

Fehler gelöst! Wie in den Kommentaren in  Entity Framework Runtime Model Adapter zu lesen ist, muss man in der ConnectionAdapter.cs private static XNamespace StoreNamespace von "http://schemas.microsoft.com/ado/2006/04/edm/ssdl" auf "http://schemas.microsoft.com/ado/2009/02/edm/ssdl" abändern.

Danach funktionierte es ohne Probleme!

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Campy am 04.05.2012 15:01.

Neuer Beitrag 04.05.2012 12:57 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 2 Jahre.
Der letzte Beitrag ist älter als ein Jahr.
Antwort erstellen


© Copyright 2003-2013 myCSharp.de-Team. Alle Rechte vorbehalten. 23.05.2013 05:14