2009-03-28 5 views
3

Normalerweise möchte ich die Datenbankverbindung selbst erstellen und ihre Lebensdauer manuell mit `using {} 'steuern. Zum Beispiel:Um Datenbankverbindung in Geschäftsobjekten einzukapseln oder nicht?

SqlConnection sqlConnection = new SqlConnection(connectionString); 
using(sqlConnection) { 
    BusinessObject myBusinessObject = new BusinessObject(sqlConnection); 
    // do stuff with the business object 
    ... 
} 

So ist es sichtbar und offensichtlich, dass ich eine Ressource verwende, die entsprechend aufgeräumt werden muss. Dies führt jedoch zu einer Menge sich wiederholender Anstrengungen. Ich bin versucht, die SQL-Verbindung innerhalb des Geschäftsobjekts zu erstellen und IDisposable darauf zu implementieren. Ich würde die Verbindung in der Dispose() Methode schließen.

using(BusinessObject myBusinessObject = new BusinessObject()) { 
    // do stuff with myBusinessObject 
    ... 
} 

Das Problem, das ich habe ist, dass es nicht so offensichtlich sein könnte, dass das Business-Objekt entsorgt werden muss, wenn Sie es im Einsatz zu sehen.

Wie würdest du es tun?

Antwort

4

Geschäftsobjekte sollten in Bezug auf die Datenbank vernünftig (oder vollständig) dumm sein. Sie sollten eine Art von Zugriffsebenenobjekt (Repository oder Datenkontext) implementieren, das weiß, wie Sie Ihre Geschäftsobjekte in der Datenbank beibehalten und die Verbindungslogik beibehalten, anstatt den Code in jedes Ihrer Geschäftsobjekte zu schreiben. Ihr Repository oder Kontext wäre wegwerfbar, so dass es nach sich selbst aufräumen könnte. @ Marcs Vorschlag, dass Sie dem Muster der Arbeitseinheit folgen, ist ein guter Vorschlag.

Sie könnten LINQtoSQL, nHibernate, Subsonic, etc. verwenden, um sie zu verwenden oder zumindest für Ideen, wie man eine gute Datenschicht strukturiert, wenn Sie darauf bestehen, Ihre eigenen zu schreiben. Aus persönlicher Erfahrung kann ich Ihnen sagen, dass die Verwendung einer vorhandenen Technologie viel einfacher ist als das Schreiben und Verwalten Ihrer eigenen Technologie.

+0

Danke für die Antwort. Der Code, über den ich hier nachdenke, ist ziemlich einfach. Ich habe NHibernate in der Vergangenheit verwendet, bin mir nicht sicher, ob ich für dieses Projekt dorthin gehen möchte. Aber wie du schon sagtest, wäre vielleicht eine Drehung durch die Quelle eine gute Übung. – dnewcome

+0

Wenn nHibernate zu viel erscheint, sollten Sie LINQtoSQL in Erwägung ziehen. Meiner Erfahrung nach ist es sehr leicht.Sie können die L2S-Entitäten entweder als DTOs betrachten oder sie mit partiellen Klassen/Methoden zu vollwertigen Business-Objekten erweitern. – tvanfosson

3

Nun, zuerst würde ich Verbindungen zum Repository verlassen.

Zweitens würde ich nicht eine Verbindung auf einem Objekt hängen bleiben - ich würde es nur für eine Einheit der Arbeit (d. H. Eine einzige Methode) verwenden. Die Chancen stehen gut, dass Sie (aufgrund von Pooling) die gleiche physische Verbindung trotzdem erhalten. Das System ist schon lange im Umgang mit solchen Dingen, so dass Sie es nicht müssen.

Der schwierigere Fall ist Transaktionen, wo TransactionScope ist viel einfacher als die Übergabe eines DB-Transaktionsobjekts herum.

+0

Ich bin damit einverstanden, Verbindungen zu halten. Ich würde die Lebensdauer des Geschäftsobjekts auf dieselbe Weise beibehalten wie bei der manuell erstellten Verbindung. Problem ist, dass andere, die die API verwenden, dies möglicherweise nicht tun. Vielleicht erstellen/schließen Sie die Verbindung bei Aufrufen der BO? Aber dann würden wir vielleicht ein Trans wünschen. später. – dnewcome

+0

@Marc - Ich hatte weniger Erfahrung mit TransactionScope, obwohl es mit LINQToSQL besser sein könnte. Wenn ich TableAdapters trotzdem verwenden würde, würde ich feststellen, dass fast alle Transaktionen auf verteilte Transaktionen umgestellt werden würden und es kein Ende der Probleme gäbe, so dass es durch die Firewall zur Datenbank funktionieren würde. – tvanfosson

+0

@tvanfosson - gutes Feedback; wie sie sagen: YMMV; -p –

0

Ich glaube nicht, dass ein Geschäftsobjekt wissen oder sich darum kümmern sollte, ob es hartnäckig ist oder nicht. Ein einzelnes persistentes Geschäftsobjekt kann nicht wissen, wann es Teil einer größeren Arbeitseinheit ist. Das ist die Verantwortung der Serviceebene. Lassen Sie die Verbindung aus den Business-Objekten heraus. Die Service-Schicht ist der richtige Ort, um Verbindungen zu erhalten, in der Regel aus einem Verbindungspool, Transaktionsgrenzen festlegen, Commit oder Rollback und Bereinigung.