Laden...

EF 6: Object-Context zu Db-Context

Erstellt von m.grauber vor 10 Jahren Letzter Beitrag vor 10 Jahren 3.685 Views
M
m.grauber Themenstarter:in
343 Beiträge seit 2010
vor 10 Jahren
EF 6: Object-Context zu Db-Context

verwendetes Datenbanksystem: <SQL-Server 2012>

Hallo Experten!

Habe nun auf EF6 geupdatet und es wird höchste Zeit, auf Db-Context umzustellen. Ich nutze den Ansatz "DB first" und daher sollten mir auch in Zukunft aus den Tabellen der Code erstellt werden.

Ändere ich im Edmx-File die Strategie auf "Keine", bekomme ich ja in der Designer.cs nichts mehr angezeigt.

  • Wo muss ich dann meine Klassen definieren? 🤔

  • Bisher waren dort alle Klassen "Partial" definiert, was für mich auch wichtig ist, da ich sie an anderen Stellen noch erweitert habe. Kann ich sie beim Db-Context auch als partial definieren?

Gibt es irgend eine gute Anleitung dazu? 🙁

Danke vielmals

Mfg
Michael

PS: Ich stelle nur Fragen, wenn ich in Büchern, im Web und in Foren nichts gefunden habe. Dumme Fragen bitte ich zu entschuldigen!

:] VISUAL STUDIO 2017 + .NET FRAMEWORK 4.5 + SQL-Server 2012 :]

16.830 Beiträge seit 2008
vor 10 Jahren

Installier Dir die "Entity Framework 6 Tools for Visual Studio"

  • Im EDMX dann einfach Rechtsklick auf eine freie Fläche.
  • Dann Add Code Generation Item
  • Dann "EF 6.x DbContext Generator" auswählen
  • Code generieren lassen

Ein paar Sachen wurden umbenannt. Kann sein, dass Du die alten generierten Elemente vorher löschen musst.

M
m.grauber Themenstarter:in
343 Beiträge seit 2010
vor 10 Jahren

Danke für die schnelle Hilfe!

Bei Microsoft habe ich folgendes gefunden:

http://visualstudiogallery.msdn.microsoft.com/66612113-549c-4a9e-a14a-f629ceb3f89a

Dort wird aber geschrieben, dass man besser mit DB-Context arbeiten sollte und das Tool nur für bestehende Anwendungen nutzen sollte.

Das von Dir beschriebene Tool hat damit also nichts zu tun und ich kann damit zukünftig über DB-Context arbeiten? Stellt das Tool den Code automatisch um?

Und warum reicht es nicht das EF über Nuget zu ziehen? Ich bin dann doch zukünftig immer auf dieses Tool angewiesen? (Was ich auch nicht sein möchte. Evtl. wird es irgendwann einmal eingestellt?)

  • Ich möchte schon gleich auf DB-Context umsteigen.

  • Kann es sein, dass es irgend wann das Tool nicht mehr gibt und ich dann sowieso umstellen müsste?

Ich möchte später nicht noch mehr Arbeit haben und würde gerne die Umstellung probieren:

Ich habe z. B. einen Methode, die mit die Verbindung öffnet und die Verbindung als Rückgabewert zurückgibt:


public static MyEntities OeffneVerbindung(...)
{
   ...
   EntityConnection MyEntityConnection = null;
   MyEntityConnection.Open();
   ...
   MyEntities myEntities = new MyEntities(MyEntityConnection);
   ...
   return myEntities;

Leider findet er in der Zeile "public static MyEntities" nach der Umstellung zu DB-Context die "MyEntities" nicht mehr. Was muss ich dann dort angeben? Bisher habe ich danach über MyEntities.Tabelle auf die Daten zugreifen können. 🙁

Danke vielmals!

Mfg
Michael

PS: Ich stelle nur Fragen, wenn ich in Büchern, im Web und in Foren nichts gefunden habe. Dumme Fragen bitte ich zu entschuldigen!

:] VISUAL STUDIO 2017 + .NET FRAMEWORK 4.5 + SQL-Server 2012 :]

16.830 Beiträge seit 2008
vor 10 Jahren

public static... für eine Contexterstellung ist nicht wirklich sauber. Du verwendest keine UnitTests oder? Denn so eine Konstellation macht das Testen schwer(er).

Das TT Script ist nichts anderes als ein (besserer) Ersatz des Standard EDMX-Generators; eben mit dem Ziel der DbContext Nutzung, was vorher so nicht vorhanden war.
Das ist ja nicht irgendein Tool sondern eine einfache Code Generierung, die Dir arbeit abnimmt (eben aus dem EDMX (XML)) die POCOs mit DbContext zu erzeugen).

Hast Du es überhaupt ausprobiert und angeschaut, was es tut, oder sind das hier nur Vermutungen?
Wenn Du auf externe Code Generierungsmaßnahmen verzichten und unabhängiger bleiben willst, dann musst Du auf EDMX ganz verzichten.

Generell sagt das ADO.NET Team: wenn Du bei 0 anfängst dann verzichte auf EDMX und verwende Code First.
Ansonsten schau Dir den Blog von ADO.NET an; da gibts die meisten (offiziellen) Beispiele.

M
m.grauber Themenstarter:in
343 Beiträge seit 2010
vor 10 Jahren

Hallo Abt!

public static ist ja nur die Methode, die mir die Verbindung zurückgibt. Dadurch kann ich sie einfach von überall aufrufen.

Die Verbindung selbst, die innerhalb der static-Methode erstellt wird ist ja dadurch nicht auch automatisch static. Es sollte daher also keine Probleme geben.

Sobald eine Verbindung nach der Benutzung später wieder geschlossen wird, räumt die GC ja trotzdem alles auf. Oder erzeugt das eine hängende Referenz?

CodeFirst oder EDMX

  • Was würdest Du empfehlen: Mit dem vorgeschlagenen Tool arbeiten oder besser gleich doch den CodeFirst Ansatz wählen?

  • Wenn ich den Db-Context+CodeFirst-Ansatz wählen würde, bekomme ich im gesamten Programm auch in gleicher Weise wie bisher (also bei ObjectContext+EDMX) Zugriff auf meine Daten und muss nur einige Namespaces und Typen ändern oder muss ich dann das komplette Verhalten meines Programms ändern?

Tausend Dank!

Mfg
Michael

PS: Ich stelle nur Fragen, wenn ich in Büchern, im Web und in Foren nichts gefunden habe. Dumme Fragen bitte ich zu entschuldigen!

:] VISUAL STUDIO 2017 + .NET FRAMEWORK 4.5 + SQL-Server 2012 :]

16.830 Beiträge seit 2008
vor 10 Jahren

Na wenn Du den Repository Pattern sauber angewendet hast musste nur die Verbindungserstellung anpassen.

Auf empfohlene Pattern wie DI hast Du nicht gesetzt, da Du mit statischen Methoden hier arbeitest; auch wenn man Deines als eine Factory ansehen könnte.
Ganz ohne Aufwand bzgl. der Verbindungserzeugung wirds nicht gehen.

Der GC behält die Connection, da ADO.NET / EF im Standard mit Connection Pooling arbeitet; aber das ist schon gewollt und korrekt so.
Wenn Du den Repository Pattern mit UoW saubre umgesetzt hast, dann solltest Du eigentlich wissen, was wann passiert.

Und zum Rest: bitte beschäftige Dich doch erst mal mit der Technologie statt die Grundlagenfragen hier zu stellen.
Nimm ne Konsoleanwendung und teste ein bisschen rum. Man lernt doch eine Technologie nicht an ner Produktivanwendung kennen..... und vorkauen müssen wir Dir das eigentlich auch nicht 😉

M
m.grauber Themenstarter:in
343 Beiträge seit 2010
vor 10 Jahren

Hallo Abt!

Erstmal großen Dank für den Link zu den Framework-Tools! 👍 👍 👍 Und vielen Dank das man hier auch mit einem weniger großen Wissensstand Hilfe erfährt! 👍

Ich habe sie inzwischen installiert und den Code bereits begonnen umzustellen. Viele Sachen sind einfach nur an anderen Stellen untergebracht und können leicht angepasst werden.

Wo ich aber richtig Probleme habe ist folgendes:

Einer Methode kann ich irgend einen Datensatz übergeben. Bisher wurde der Parameter so übergeben:


MyDB.Kunden kunden = myEntities.Kunden.Where(...).FirstOrDefault();

MyMethode(System.Data.Entity.Core.Objects.DataClasses.EntityObject MyEObject){
}

Nach der Umstellung kommt natürlich beim Parameter "EntityObject" ein Fehler.
Darf ich hier stattdessen "Object MyEObject" angeben oder gibt es da etwas spezielleres, was benutzt werden sollte?

Außerdem gibt es keine Refresh-Methode mehr, bzw. sitzt sie wo anders:


myEntities.Refresh(StoreWins, kunden)

Jetzt könnte ich es scheinbar so lösen:


var context = ((System.Data.Entity.Infrastructure.IObjectContextAdapter)myEntities).ObjectContext;
context.Refresh()

Dann nutze ich aber doch wieder über den ObjectContextAdapter indirekt den ObjectContext, den ich ja eigentlich vermeiden will. Kann ich das nicht anders und direkt lösen?

Und hier mein größtes Problem:


kunden.PropertyChanged += new PropertyChangedEventHandler(_kunden_PropertyChanged);

Warum gibt es kein PropertyChanged mehr? Hierzu habe ich nur sehr seltsame Lösungen gefunden, bei der die ..tt-Datei geändert werden muss. Das möchte ich natürlich unbedingt vermeiden! Gibt es dort etwas anderes?

Tausend Dank!

Mfg
Michael

PS: Ich stelle nur Fragen, wenn ich in Büchern, im Web und in Foren nichts gefunden habe. Dumme Fragen bitte ich zu entschuldigen!

:] VISUAL STUDIO 2017 + .NET FRAMEWORK 4.5 + SQL-Server 2012 :]

16.830 Beiträge seit 2008
vor 10 Jahren

Normalerweise solltest Du gar nichts am Kontext pfuschen, wenn Du Unit of Work korrekt umsetzt.
Wenn beim einem Update es in der Zwischenzeit eine Änderung gibt wird eine Exception geschmissen. Auf die kannst Du in der Anwendung reagieren und so zB den Nutzer über die überschriebene Aktualisierung informieren.


MyMethode(System.Data.Entity.Core.Objects.DataClasses.EntityObject MyEObject){
}

hört sich nach sehr sehr unsauber gelöstem Code an. Was soll das tun und wieso steckt es nicht im Repository?

kunden.PropertyChanged +

was soll das sein? Was ist kunden? Eine Entity oder eine Collection oder ein Context?

M
m.grauber Themenstarter:in
343 Beiträge seit 2010
vor 10 Jahren

Hallo Abt!

Ich habe den Code auch nur übernommen und die Umstellung auf DB-Context wird nun notwendig. Alles neu zu schreiben kommt nicht in Frage. Auch ich habe noch viele Defizite.

Daher bitte trotzdem versuchen zu Helfen! Danke 👍


MyMethode(System.Data.Entity.Core.Objects.DataClasses.EntityObject MyEObject){
}

Da werden z.B. Änderungen protokolliert. Übergeben wird ein Datensatz aus einer beliebigen Tabelle der Datenbank, z. B. kunde aus der Kunden-Tabelle oder lieferant aus der Lieferanten-Tabelle. Kann ich also Object verwenden oder gibt es ein spezielleres Objekt dafür?


kunden.PropertyChanged += new PropertyChangedEventHandler(_kunden_PropertyChanged); 

Davor ist "kunden" so definiert: public Kunden kunden = new Kunden();

Hier soll sofort Code ausgeführt werden, sobald sich etwas an irgend einem der Felder (z. B. Kundenname, Ort, Straße usw.) ändert. Bisher als EntityObject vor der Umstellung hat es einwandfrei geklappt und das PropertyChanged korrekt ausgelöst. Wie kann das nun ausgelöst werden, ohne den ganzen Code umzustellen?

Für die von mir geschriebene Refresh-Lösung gibt es keinen anderen Ansatz?

Nochmals vielen vielen Dank!!!

Mfg
Michael

PS: Ich stelle nur Fragen, wenn ich in Büchern, im Web und in Foren nichts gefunden habe. Dumme Fragen bitte ich zu entschuldigen!

:] VISUAL STUDIO 2017 + .NET FRAMEWORK 4.5 + SQL-Server 2012 :]

16.830 Beiträge seit 2008
vor 10 Jahren

Du musst nicht immer alles fett schreiben. Ich les es auch so 😉

1:1 übernehmen ist nicht. Dafür ist der neue Context nicht geeignet.
Das sind jetzt leider Lehrstunden, wenn man die Schichten nicht korrekt modular entwickelt hat 😉

Du musst Dich schon an die saubere Umsetzung von UnitOfWork und Repository Pattern machen; wenn UnitOfWork nicht passt, dann kriegst Du immer und immer wieder Probleme, dass Du irgendwas von Hand auf Modified stellen musst oder irgendwas protokollieren musst.

PropertyChanged ist nicht konform mit POCOs und ist daher bei einem POCO Generator nicht enthalten.
Wenn Du sowas willst musst Du das alles selbst um Code umsetzen.

Du kannst den Context nicht so umbiegen wie Du willst. Du musst halt schon damit arbeiten, was er Dir zur Verfügung steht.
Ich acker auch nich mit nem Ferrari die Felder um - dafür isser nicht gedacht. 😉