Laden...
M
Benutzerbeschreibung
Visual Studio 2012 C# !NET Framework 4 - FÜR WINDOWS XP UNTERSTÜTZUNG! WPF, DataBinding (einschichtig) über Entity Framework, SQL-Server 2000-2012

Forenbeiträge von m.grauber Ingesamt 343 Beiträge

19.11.2021 - 10:08 Uhr

Hallo Abt

Danke! Ja das ist allerdings eine ältere Anwendung die ich übernommen habe und ich darf sie nicht komplett umbauen.

Hier geht es aber nicht um die Datenspeicherung, sondern nur um die Darstellung beim Öffnen des Fensters. So etwas sollte eigentlich nicht passieren.

Vielleicht hat noch jemand eine Idee?

18.11.2021 - 16:11 Uhr

Hallo Jamikus!

Danke für die wirklich clevere Idee! - Ja ich habe die Position gefunden.

Im Loaded wird bLF immer mit false angezeigt, aber im Loaded werden auch einige Radiobox_Checked() aufgerufen und sobald der Debugger da im Einzelschritt hineinspringt, wird darin teilweise bLF=true angezeigt! Nach dem Herausspringen aus der Radiobox_Checked() ist aber bLF im Loaded wieder korrekterweise false!

Im Loaded ändert es sich also nicht, aber in den Untermethoden ist der Wert bLF teilweise(!) falsch.

(Nein ich habe keine lokale Variable in den Untermethoden, die auch bLF heißt. Wenn ich in der Untermethode in der Abfrage if (bLF==true) den Cursor auf bLF platziere und dann F12 drücke, komme ich genau zu meiner definierten bLF - Variable aus dem Window.

Ich bin total ratlos.

18.11.2021 - 14:12 Uhr

Hallo!

In einem C# WPF-Projekt wird in "Window1 (Hauptfenster)" das "Window2" geöffnet und darin "Window3". (Jeweils mit einer lokalen Var und .Show())


public partial class Window3 : Window
{
         private bool bLF = false;
         ...
}

Im Window3 wird am Ende von Loaded() bLF auf true gesetzt.
Später wird Window3 geschlossen und danach von außerhalb(!) dieser Fenster Window3=null gesetzt und danach Window2 ebenfalls geschlossen und Window2=null gesetzt und danach jeweils GC.Collect() sowie GC.WaitForPendingFinalizers() ausgeführt. (Ja ich habe hier oft gelesen, GC ist nicht notwendig).

Öffnet man nun wieder Window2 und dann Window3 jeweils normal mit .Show(), ist in Window3 bLF immer noch auf true gesetzt, obwohl das Fenster Window3=null gesetzt war!

So etwas habe ich bislang noch nie gesehen. Scheint eine hängende Referenz zu sein?

Ich habe nun versucht zu sehen, wo genau bLF auf true umgestellt wird:


internal Window3()
{
            MessageBox.Show("Zeile1 bLF=" + (bLF == true ? "true" : "false"));
            InitializeComponent();
            MessageBox.Show("Zeile 2 bLF=" + (bLF == true ? "true" : "false"));
            bLoadedFinished = false;
            MessageBox.Show("Zeile 3 bLF=" + (bLF== true ? "true" : "false"));
}

Beim erneuten Öffnen ist bLF in Zeile 1 false (so wie es sein soll) und dann aber nach InitializeComponent() seltsamerweise auf true, obwohl es erst am Ende von Loaded auf true gesetzt wird! bLF wird sonst wirklich nirgendwo auf true gesetzt.

Wenn man zum Test bLF vor dem Schließen des Window3 auf false setzt, ist es dann nach dem Erneuten Öffnen von Window3 korrekt auf false! Es behält also seinen alten Wert, obwohl das Fenster mit .Close() und window3=null geschlossen wurde und der GarbageCollection bereinigt wurde. Das erneute Öffnen erfolgt ca. 1 Min. danach, wodurch eigentlich die GC genügend Zeit hätte den Speicher zu bereinigen.

Im Windows-Task-Manager geht die Speicherauslastung beim Schließen des Window3 schon etwas herunter, aber nie auf die Werte vor dem Öffnen des Fensters Window3. Ja, ihr schreibt, der Taskmanager ist ungenau.

Die einzige Referenz die auf Window3 besteht ist eine ObservableCollection außerhalb der Fenster mit einer Klasse die ein Feld "public Window Window { get; set; }" besitzt und der das Fenster zugewiesen wird, wenn es geöffnet ist. Allerdings wird dieses Feld dann beim Schließen auch auf null gesetzt und danach das komplette Item mit .Remove(item) entfernt.

Was läuft da falsch?

Vielen Dank!

10.08.2020 - 12:40 Uhr

Hallo Abt und MrSparkle!

Ich bin jetzt aus dem Urlaub zurück; Gesund.

Danke für die Antworten und den Link. Ich werde es beherzigen und mir nun Planungszeit für die Umsetzung in den Kalender eintragen.

Ich wünsche eine vielversprechende Woche!

15.07.2020 - 14:23 Uhr

Hallo Abt!

Es ist schwierig, wenn man immer angetrieben wird, sofort neue Ergebnisse zu liefern und keine Zeit für diese Dinge einplanen kann.

Ich denke in größeren Firmen ist das besser gelöst.

Kennst Du auch keine gute Seite zur Umstellung von EF 6 auf EF Core in englisch? Vielleicht hat noch jemand einen Tipp.

Nochmals vielen Dank!

15.07.2020 - 12:29 Uhr

Hallo Witte!

Danke, aber damit wäre nur ein Select möglich, kein zurückschreiben in die Tabelle "Einladungen".

Hallo Abt!

Danke auch Dir nochmals! Zeitlich ist es für mich sehr schwer mich neben meiner Arbeit auch mit den Änderungen etc. zu befassen. Ich hatte das schon im Hinterkopf auf dem Radar, aber mich noch niemals damit befasst. Erschwerend kommt hinzu, dass ich beim EF den Designer nutze und den "Database First"-Ansatz.

Ich weiß, es gibt einige Infos zur Umstellung auf EF Core. Aber kennst Du hierzu zufällig eine gut gemachte und verständliche Seite auf Deutsch?

Vielen Dank!

15.07.2020 - 11:28 Uhr

Hallo Abt!

Danke für die ausführliche Antwort! Das hilft wirklich sehr!

Ja, ich nutze noch nicht den EF Core - Sollte ich irgendwann umstellen, weil der normale EF irgendwann nicht mehr unterstützt wird? Wann wird das vermutlich sein? - Microsoft behält sich da sehr bedeckt.

https://docs.microsoft.com/de-de/ef/efcore-and-ef6/porting/

Hier schreibt Microsoft:

"...Aufgrund der wesentlichen Änderungen in EF Core wird nicht empfohlen, eine EF 6-Anwendung auf EF Core umzustellen – es sei denn, es gibt einen zwingenden Grund für eine solche Änderung. Sie sollten den Wechsel von EF 6 nach EF Core weniger als Upgrade, sondern als eine Portierung betrachten..."

Könnte es sein, dass das normale EF ab einem bestimmten VS nicht mehr genutzt werden kann? (z. B. VS 2021, 2023, 2025, 2027 etc.?)

Nun nochmals zum Problem:

Kunden.Name soll nur beim Lesen gleichzeitig aus der Tabelle Kunde ausgelesen werden (damit der Benutzer den Kundennamen im Klartext sieht, aber beim folgenden Speichern natürlich nicht zurückgeschrieben werden.

Ich dachte, vielleicht kann man im Linq mit "select new {…." alle Felder angeben und dann das Ergebnis in eine Entität vom Typ "Einladung" vornehmen. - Und in der partial class Einladung ist ja dieses (public string Name { get; set; } definiert, in das der Kundenname beim Linq-Befehl übernommen werden kann.

Wenn es so nicht geht, habe ich vermutlich den Post in Stack Overflow falsch verstanden? (letzter Eintrag von Sean, ganz unten)

Ein Locking ist in diesem Programmteil nicht notwendig.

Wenn ich nach dem Linq auf die Tabelle "Einladung" das Feld "Name" manuell beschreibe, klappt ja ein anschließender SaveChanges() auch korrekt und der Befehl ignoriert einfach dieses "lokale" Feld "Name".

Einen zweiten Select und eine foreach-Ersetzung würde ich gerne vermeiden.

Du bist sehr weit und hast eine enorm große Kenntnis und würdest vieles auch ganz anders realisieren. Evtl. kann man diesen Select aber dennoch in einer möglichen Form realisieren.

Danke und schöne Grüße!

13.07.2020 - 13:20 Uhr

Hallo!

Ich nutze VS 2017, C# und den SQL-Server.

Hier ein vereinfachtes Beispiel (was natürlich nicht sehr sinnvoll ist):

Eine SQL-Server Tabelle "Einladung" enthält folgende Spalten:
EinladungID
KundeID
Hinweis

Eine zweite Tabelle "Kunden" enthält folgende Spalten:
KundeID
Name

1.) Select: Alle Kunden zur Einladung Nr. 100 heraussuchen:


var i = (from e in dataEntities.Einladung
                         where e.EinladungID==100
                         select o).ToObservableCollection<Einladung>(...

-> Das klappt. Man erhält eine ObservableCollection mit den Spalten EinladungID, KundeID und Hinweis und ich kann auch Änderungen mit SaveChanges() speichern.

2.) Nun erweitere ich im C#-Code die partielle Klasse "Einladung"
(public partial class Einladung)
um ein Feld "Name" (public string Name { get; set; }), welches nicht in der SQL-Tabelle "Einladung" existiert, aber den Benutzer in der Observable Collection angezeigt werden soll. Damit würde er auch immer den aktuellen Namen aus der Tabelle "Kunden" sehen, auch wenn der sich einmal ändert.

Ohne Probleme habe ich durch diese Erweiterung ein zusätzliches Feld "Name", das ich auch beliebig beschreiben und ändern kann und welches gewünschterweise bei SaveChanges() natürlich nicht in die Tabelle "Einladung" zurückgeschrieben wird. Alle anderen Änderungen an der Tabelle "Einladung" werden aber mit SaveChanges() korrekt in den SQL-Server zurückgeschrieben.

--> Frage. Wie kann ich aber per Linq-Join dieses Feld "Name" zusätzlich auslesen, so dass es bei SaveChanges() ignoriert wird. Das hier klappt leider nicht:


var i = (from e in dataEntities.Einladung
                         where e.EinladungID==100
                         join a in dataEntities.Kunden on e.KundeID equals a.KundeID
                         select e, a.Name).ToObservableCollection<Einladung>(...

  • Es sollte so ausgelesen werden, dass alle Änerungen per SaveChanges() in die Tabelle "Einladung" gespeichert werden können, ohne das das Feld "Name" berücksichtigt wird.

  • Ich möchte ungern einen zweiten Select auf die Kundentabelle ausführen und dann per foreach alle Datensätze in der Observable Collection einzeln durchgehen müssen.

  • Ein T-SQL-Befehl würde diesen Join zwar machen, jedoch kann ich dann nicht mehr mit SaveChanges() Änderungen zurückspeichern.

Folgenden Lösungsvorschlag habe ich entdeckt:

https://stackoverflow.com/questions/23848259/linq-updating-different-table-after-join-process

Umformuliert wäre das so, das klappt leider nicht:


var i = (from e in dataEntities.Einladung
                         where e.EinladungID==100
                         join a in dataEntities.Kunden on e.KundeID equals a.KundeID
                         select new { e, a }).Select(result => { result.e.EinladungID = Einladung.EinladungID; result.e.KundeID = Einladung.KundeID; result.e.Hinweis = Einladung.Hinweis; result.a.Name = Name; return result}).ToObservableCollection<Einladung>(…

Wie bekommt man so etwas hin?

Danke sehr!

11.03.2020 - 09:56 Uhr

Hallo Abt

In Ordnung. Verstanden. Vielen Dank für die Infos. Ihr tut hier wirklich einen sehr guten Job, auf diese Fragen einzugehen! 👍

Mit freundlichem Gruß

10.03.2020 - 14:16 Uhr

Hallo Abt

In Ordnung. Ich dachte im Forum gibt es dazu Erfahrungswerte und man kann sich dazu einfach austauschen und nicht, dass jeder selbst immer von vorne anfängt. 🙁

Ich werde dann viele Daten erzeugen und dann Tests fahren.

Danke trotzdem für die Antworten.

Mit freundlichem Gruß

10.03.2020 - 12:35 Uhr

Hallo Abt und T-Virus!

Ersteinmal vielen Dank für die Infos. Ich war leider unterwegs.

Nein, es sollen nicht alle Felder indiziert werden, sondern natürlich wie gesagt nur die, die in in WHERE-Klauseln auch zum Vergleich abgefragt werden und die in JOIN-Verbindungen angegeben sind. Bei anderen Tabellen können das auch entsprechend mehr Felder werden. Mein Beispiel mit der Kundentabelle ist nur ein Beispiel und steht stellvertretend für alle Tabellen.

Diese werde ich nun mit "CREATE INDEX IX_Kunden_Nachname ON Kunden(Nachname ASC)" usw. indizieren.
Das können je nach Tabelle zwischen 2 und 8 Indizes sein.
Auf die Spalten mit den Foreign Keys werde ich auch Indizes setzen.

In der Lösung wird die Kundentabelle und auch alle anderen Tabellen eher seltener bearbeitet und es sollen sehr viele Einträge (z. B. auch > 100.000) gespeichert werden.

  • Zur Indizierung von Guid-Spalten habe ich im Netz sehr widersprüchliche Infos gefunden. Einige sagen sogar, dass sei Kontraproduktiv. Hier bin ich etwas verwirrt und habe leider zu wenig Datensätze, um die Differenz zu Messen. - Könnt ihr bitte zumindest dazu noch ein klares Ja oder Nein geben, wenn ihr damit Erfahrungen habt?

  • Würdet ihr für die Spalte Nachname und Vorname statt normaler Indizes aus Performancegründen lieber **Volltextindizes **verwenden?

Nochmals vielen Dank!

Mit freundlichem Gruß

06.03.2020 - 15:34 Uhr

Hallo Abt,

Entschuldige, das war ein wirklich dummer Schreibfehler. 😦 Ich meine NON-Clustered. Ich haben den Text oben gleich geändert. Ich habe ja bereits einen Primary Key, der auch die Sortierung bestimmt!

Diese Tabelle ist wie gesagt nur für das Verständnis beim Fragen. Natürlich füge ich nur für die Felder einen Index ein, die ich in den größeren "SELECT …."-Anweisungen auch abfrage und diese Indizes sind nur Beispiele für Indizes bei den verschiedenen Feldtypen an den verschiedensten Orten. Das kommt um Himmelswillen so nicht in die Datenbank!

Indexed View's kommen allerdings nicht in Frage.

Ich habe mich natürlich schon vorher damit etwas befasst und das waren die Fragen, die noch übrig sind.

Könntet ihr sie bitte dennoch ganz knapp (j/n) beantworten?

Das würde wirklich sehr weiterhelfen!

An T-Virus: Danke auch Dir für die Antwort!

Natürlich ist die Datenbank relational und muss es bei den Daten auch sein. Leider ist in meinem Beispiel die Tabelle und die Felder etwas dumm gewählt, aber es soll einfach verständlich sein.

Also soll ich den Index nicht mit "IX_" beginnen? - Beim Anlegen des Index über das Managementstudio und auch im Internet lese ich das immer wieder.

  • Wie soll ich dann den Index benennen? (IX hinten anstellen wie z. B. "Kunden_Nachname_IX"?

Danke!

06.03.2020 - 14:04 Uhr

Hallo,

Meine Fragen bezieht sich auf SQL-Server (gekauft) und die kostenlose SQL-Server-Express-Edition und dienen zur Performance-Steigerung beim Lesen von Daten aus einem C# Projekt heraus.

Ich kann die Performance bei den wenigen Datensätzen leider nicht testen. Sicher habt ihr schon viel Erfahrung damit.

1.) Durch die Prozessor-Beschränkung beim SQL-Server-Express könnte es sein, dass sich die weiteren Fragen dann anders beantworten lassen, weil sich die Arbeitslast ändert und z. B. die Express-Editions dann mit weniger Indizes klar kommt. - Ist dies so? (Diese Frage bitte erst am Schluss beantworten)

Allgemeine Infos:

  • Alle Tabellen haben bereits einen Primary Key, daher kann ich zur Performancesteigerung immer nur noch Non-Clustered-Indizes anlegen
  • Die Erhöhung des Speicherplatzes durch neue Indizes ist problemlos möglich. Es wird keine Platzprobleme geben. Die Performancesteigerungen sind das Wichtigste.
  • Die Geschwindigkeit der Datensatzerstellung ist ebenfalls vernachlässigbar und kann durch eine bessere Indizierung auch gerne etwas länger dauern.
  • Zugriff ist aus C# heraus teils über T-SQL-Anweisungen und teils über Linq.
  • Es sollen einmal sehr viele Datensätzen in die Kunden-Tabelle und in zugehörige relationale Tabellen.
  • In möglichen Foreign-Keys sollen keine automatischen Regeln etc. genutzt werden.

Damit es einfache Antworten geben kann, hier ein einfaches Bsp.: eine Tabelle Kunden mit den Feldern

 PKKunden int NOT NULL (Primary Key)
 Nachname nvarchar(70) NOT NULL
 Vorname nvarchar(30) NOT NULL
 Kundenart int NOT NULL
 Kundeseit datetime NOT NULL (Standardwert: 1.1.1900)
 Kundeaktiv bit NOT NULL
 Kundenid uniqueidentifier NOT NULL

Ich würde nun gerne folgende Indizes erstellen:
"CREATE INDEX IX_Kunden_Nachname ON Kunden(Nachname ASC)" &quot;CREATE INDEX IX_Kunden_Vorname ON Kunden(Vorname ASC)&quot; &quot;CREATE INDEX IX_Kunden_Kundenart ON Kunden(Kundenart ASC)&quot; &quot;CREATE INDEX IX_Kunden_Kundeseit ON Kunden(Kundeseit ASC)&quot; &quot;CREATE INDEX IX_Kunden_Kundeaktiv ON Kunden(Kundeaktiv ASC)&quot; &quot;CREATE INDEX IX_Kunden_Kundenid ON Kunden(Kundenid ASC)&quot;

2.) Ich würde für alle Felder per "CREATE INDEX" Indizes erstellen, nach denen ich filtere. Gibt es beim SQL-Server eine Obergrenze, ab der durch die vielen Indizes dann die Abfrage evtl. sogar noch länger dauert als ohne oder mit weniger Indizes? (Ich kenne das von anderen Datenbanken, dass dann Abfragen ab z. B. 7 Indizes in einer Tabelle langsamer werden.)

3.) Sind die oberen Indizes die performanteste Art, wenn man dann auf die Tabellenfelder per T-SQL und WHERE-Klausel (z. B. "WHERE Kundenart=2") zugreift?

4.) Sind die oberen Indizes auch die performanteste Art, wenn man auf die Tabellenfelder per Linq-Where zugreift?

5.)
a) Ist "CREATE INDEX" die performanteste Art, wenn man auf dieses Feld später per JOIN zugreift ODER ist es performanter per Foreign-Key (z. B. "ALTER TABLE [dbo].[Kunden] WITH NOCHECK ADD CONSTRAINT [FK_Kunden_Kundenart] FOREIGN KEY([Kundenart]) REFERENCES [dbo].[Kundenart] ([PKKundenart]) NOT FOR REPLICATION")?
b) Oder verlangsamt evtl. sogar der Foreign-Key?

6.) Soll trotz Foreign-Key dennoch auch immer ein Index erstellt werden, damit die Abfragen schneller sind?

7.) Gelten die oberen Antworten dann wirklich für alle Feldtypen (z. B. nvarchar, bit, tinyint, int, datetime etc. (außer z. B. Memofeldern)

8.) Wie sieht es mit GUID's in uniqueidentifier-Feldern (NOT NULL) aus? Gilt das auch dafür?

9.) Mit welcher Art Index kann man die Performance steigern, wenn man z. B. ein nvarchar-Feld mit "WHERE Nachname LIKE %müller%" abfragt?

Vielen Dank im Voraus!!!

Mit freundlichem Gruß

30.08.2018 - 13:22 Uhr

Hallo Khalid!

Tausend Dank für die super schnelle und präzise Info! Klappt super! 👍 👍 👍

Woher ihr das immer wisst... 😉

Ich hätte nie nach CTE gegoogled.

Noch eine wirklich erfolgreiche Rest-Woche!

29.08.2018 - 16:09 Uhr

Hallo Experten!

Leider habe ich nichts gefunden und weiß auch nicht so recht nach welchem Suchbegriff ich suchen soll.

Ich möchte in einer Abfrage in einer Spalte je nachdem welche Kriterien pro Datensatz erfüllt sind mit geschachtelten CASE WHEN ... END mir Werte ermitteln und mit "AS" in die Spalte "MeinWert" überführen.

Zusätzlich möchte ich weitere Spalten erzeugen, die auf das Ergebnis in "MeinWert" zugreifen sollen und diesen Wert als Ausgang für anderes nutzen sollen.

Ich stelle es mir so vor:

SELECT CASE WHEN .... THEN TableField1 ELSE TableField2 END AS MeinWert, TableField2, TableField3,
CASE WHEN ... THEN MeinWert ELSE 0 AS Ergebnis1,
CASE WHEN ... THEN MeinWert ELSE 0 AS Ergebnis2,
CASE WHEN ... THEN MeinWert ELSE 0 AS Ergebnis3
FROM ....

oder

SELECT CASE WHEN .... THEN TableField1 ELSE TableField2 END AS MeinWert, TableField2, TableField3,
CASE WHEN ... THEN [1] ELSE 0 AS Ergebnis1,
CASE WHEN ... THEN [1] ELSE 0 AS Ergebnis2,
CASE WHEN ... THEN [1] ELSE 0 AS Ergebnis3

Der CASE WHEN, der später MeinWert ermittelt, ist später mehrfach verschachtelt und sollte daher nur 1x berechnet werden. Da ich mit den Spalten Ergebnis1 - 3 mehrfach darauf zugreifen möchte will ich den SQL-Befehl schnell und kurz halten.

Wie kann ich nun auf die 1. errechnete Spalte "MeinWert" zugreifen? Das klappt weder mit dem mit "AS" generierten Spaltennamen noch mit der Spaltennummer [1] die z. B. bei der Sortierung angegeben werden kann.

Später kommt zu allem "Übel" auch noch eine Gruppierungsfunktion über die Ergebnisse dazu, daher sollte die Lösung recht einfach sein.

Danke und gute Arbeit!

SQL-Server ab 2008

30.03.2016 - 13:10 Uhr

Hallo T-Virus!

Danke auch Dir für die tolle Hilfe! 👍 Ich werde es nun erst einmal mit einer Schnittstelle realiseren, da

Wenn bereits die Funktionalität zum Verbindungsauf/Abbau und die Zugriffe über das EF implementiert ist, versuche ich diese natürlich zu nutzen, statt den Aufbau - mit all seinen Facetten und teils geloggten Einträgen in der DB - in einer anderen Technologie nur für diese eine Abfrage nachzubauen.

Sollte ich es noch dynamischer benötigen, muss ich dann eben wirklich anders zugreifen.

Nochmals vielen Dank an alle!

30.03.2016 - 13:06 Uhr

Entschuldige Abt!

Deiner ersten Antwort entnahm ich, dass es "sehr fehleranfällig" sei, aber ich habe nicht daraus gelesen, dass es nicht möglich ist.

Das es eine typisierte Sprache ist, ist klar.

Aber wer kann sich heraussuchen, welche Projekte er übernimmt und mit welcher Technologie dort bereits gearbeitet wird? Abgesehen davon ist das EntityFramework eine sehr gute und schnell umzusetzende Sache!

Wenn bereits die Funktionalität zum Verbindungsauf/Abbau und die Zugriffe über das EF implementiert ist, versuche ich diese natürlich zu nutzen, statt den Aufbau - mit all seinen Facetten und teils geloggten Einträgen in der DB - in einer anderen Technologie nur für diese eine Abfrage nachzubauen.

Wenn nun die Anforderung kommt, so etwas dynamisches zu ermöglichen, sage ich sicher nicht, dass ich dafür nun erst einmal für das gesamte Projekt eine andere Technologie benötige und alles neu programmieren muss.

Ich besitze Jahrzehnte Erfahrung in der Softwareentwicklung unter verschiedensten Entwicklungsumgebungen und DBMS. Sicher derzeit noch nicht so viel in C#.

Wenn ein Linq-Befehl dies problemlos in eine anonyme Liste ermöglicht, aber ein ExecuteStoreQuery nicht, muss Microsoft doch etwas vergessen haben?

Da andererseits bei Linq der Teilaspekt DynamicLinq fehlt, kann man vielfach im Internet lesen - Das sind nicht alles Laien.

**
Vielen Dank für den Tipp mit dem Interface, ich habe es ebenfalls schon an anderen Stellen genutzt, bin aber hier nicht auf diese Idee gekommen! 👍**

Das mit dem "pfuschen" finde ich daher nicht freundlich.

Wenn Microsoft wieder neue Technologien herausbringt, müssen wir uns alle auf andere Entwicklungsumgebungen umstellen und sind dann alle erst einmal Laien.

29.03.2016 - 15:57 Uhr

Wenn ich andererseits nun doch verschiedene vorgegebene Klassen nutze: Z.B. Klasse1, Klasse2 könnte ich auch schon viel erreichen mit:

List<Klasse1> Liste1
List<Klasse2> Liste2

aber leider kann ich sie nicht strongly typed über einen immer gleichen Namen ansprechen. Ich hätte aber dann gerne das:


List<???> MeineListe = null;

if (i==1)
  MeineListe=Liste1
else
  MeineListe=Liste2

In jedem Fall möchte ich über "MeineListe" auf die Liste zugreifen, wobei sie je nach Bedarf andere Felder aufweist.

Wie macht man so etwas?

29.03.2016 - 15:22 Uhr

Hallo T-Virus!

Danke für die Info!

Das Mappen einer eigenen Klasse ist nicht möglich, da erst der Anwender bestimmt, welche Spalten benötigt werden und diese aus verschiedenen Tabellen kommen können. Das wären also unendlich viele Klassen in unendlichen Kombinationen. Auch die Where-Klausel könnte dynamisch sein.

Folgendes zu DataTable habe ich gefunden:
"As the question/answer you linked to tells you, ExecuteStoreQuery returns entities - it cannot return a DataTable."
http://stackoverflow.com/questions/19796078/executestorequery-entityframework

Ist dort auch nur über eine bekannte Entität <MyEntity> gemacht worden.

Da der Code danach bereits steht und auf die Liste zugreift, tu ich mir schwer, etwas über die Columns auszulesen und dann in eine Liste einer Klasse zu schreiben, die ich erst zur Laufzeit(!) erzeugen müsste.

Ich werd's jetzt mal mit DynamicLinq versuchen.

Evtl. hat ja noch jemand einen Tipp (Abt?) oder Microsoft erweitert mal schnell C#, weil ich sicher nicht der einzige User bin, der so etwas braucht😁

24.03.2016 - 13:10 Uhr

Dankeschön für die Antwort.

Ja, das ist mir vollkommen klar. Aber je nachdem was ein Benutzer im laufenden Programm auswählt sollen unterschiedliche Spalten mit unterschiedlichen Typen zurückgeliefert werden.

Ich handle das Ergebnis dann schon richtig.

Kannst Du mir sagen, wie die richtige Syntax dafür lautet?

Danke

24.03.2016 - 12:09 Uhr

SQL-Server 2008, EntityFramework, VS2015

Hallo!

Bei einem ähnlichen Thema hatte ich bereits schon einmal nachgefragt: "[erledigt] Entity Framework - Nur einzelne Spalten mit CreateQuery auslesen" und scheinbar ist das nur per ExecuteStoreQuery möglich.

Da ich nun einen ExecuteStoreQuery ausführe und mir die Felder je nach Abfrage aus verschiedenen Tabellen hole und zusammenführe, muss es doch möglich sein, diese in eine ganz normale Liste mit den richtigen Feldnamen und Feldtypen zu überführen:


ExecuteStoreQuery<dynamic>("SELECT ...").ToList()
ExecuteStoreQuery<dynamic>("SELECT ...").ToList<dynamic>()

...liefern leider nur immer Listen mit Object-Typen.

Auch <List>, <List<dynamic>, <IENumerable<dynamic>> funktionieren nicht.

teils erhalte ich die Fehlermeldung:

Fehlermeldung:
Der Ergebnistyp 'System.Collections.Generic.IEnumerable`1[System.Object]' darf nicht abstrakt sein und muss einen Standardkonstruktor enthalten.

Ich benötige aber eine Liste mit den richtigen Feldnamen und Feldtypen wie sie mir z. B der folgende Linq-Befehl zurückgibt:


var Liste = (from p in ... select new {Kunde.ID, Kunde.Name}).ToList()

Dies liefert nämlich eine "System.Collections.Generic.List1[[&lt;&gt;f__AnonymousType87[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, ...", die ich weiter nutzen kann.

Auch das half mir nicht weiter:
[gelöst] Generics: Abstrakte Klassen und IEnumerable

Kann mir jemand als Ostergeschenk sagen, wie es richtig gemacht wird? 🤔

Dankesehr und schöne Ostern!

06.10.2015 - 11:01 Uhr

Hallo!

Ich habe nun den Ablauf so gestaltet, dass ich danach nicht mehr auf das Dokument zugreifen muss. Damit ist das Problem erledigt.

Die Postinghinweise werde ich zukünftig berücksichtigen. Danke!

02.10.2015 - 14:05 Uhr

Hallo!

In einer Variable wird ein offenes Excel-Dokument gehalten. Der Zugriff klappt problemlos und ich kann das Dokument auch über diese Variable per Befehl schließen.

Leider kann es sein, daß der Benutzer Excel per "X" schließt - also von "außen". Wenn ich danach im Programm unwissend auf die Variable zugreife, kommt eine Fehlermeldung > Fehlermeldung:

DisconnectedContext . (Hier im Forum nur in 2 anderen Zusammenhängen auftetreten)

Bevor ich mit der Variable weiterarbeite muß ich also prüfen, ob das Dokument noch offen ist. Ich habe alles mögliche versucht, aber leider erscheint bei dieser Prüfung trotzdem diese gleiche COM-Fehlermeldung.

Hier meine Prüfungen:

if (ObjektDokument != null)             // ist in diesem Fall nicht null und Fehler
if (ObjektDokument.Name != null)   // Fehler

Dann das obere gekapselt in eine trycatch-Konstruktion: Fehler tritt im try trotzdem auf, danach wird aber korrekt das catch abgearbeitet. - Aber der Fehler soll ja eigentlich unterdrückt werden! Ich weiß dann zwar, daß das Dokument zu ist, aber der Fehler lässt sich nicht unterdrücken.

Dann das obere per Action mit und ohne trycatch versucht. Auch einen SafeExecutor versucht.

>> Der Fehler wird bereits beim übergeben der ObjektDokument-Variable in eine Methode ausgelöst.

Wie kann ich diesen Fehler nur unterdrücken? - Am liebsten natürlich in einer Methode, der ich das ObjektDokument übergebe - damit ich die Methode an mehreren Stellen einsetzen kann und ohne die sperrige trycatch-Konstruktion im Code auskomme 🙁

Danke

29.09.2015 - 16:31 Uhr

Hallo Taipi88!

Bombig - Danke! - Mein Fehler gefunden, das hat mir sehr geholfen!!! 👍 👍 👍

Mein Code sah ähnlich aus. Ich hatte beim "Add" anstatt einem Missing nur null verwendet und SaveAs nicht per InvokeMember aufgerufen und die Parameter Dateiname und Format als string bzw. int übergeben.

Nach Umstellung dieser Sachen kam trotzdem noch ein Fehler, also ging ich nochmals alles durch: Ich baute @Pfadnamen und @Dateiname mit "&quot; zusammen und daher hatte ich "\", d. h. im Debugger wurde "\\" angezeigt. Nun stattdessen Path.Combine genutzt und es klappt!

Dein Code u.a. mit der Verwendung von Missing und InvokeMember ist wesentlich besser, weshalb ich dies nun auch nutze.

Einen schönen Nachmittag!

28.09.2015 - 11:26 Uhr

Hallo!

Leider komme ich wirklich nicht weiter und der "DefaultFilePath" wird auch ignoriert. Das ist doch eine rudimentäre Funktion die eigentlich klappen müsste? Bei Word ist es ja auch möglich. Speichert ihr Eure Excel-Dokumente nicht, daß das nicht auffällt?

🙁

22.09.2015 - 14:31 Uhr

Hallo Jamikus!

noch eines der vielen tausend Automations-Zusatztools möchte ich von Anfang an nicht nutzen. Ich habe mir so etwas bereits am Anfang vor der Automationsarbeit angesehen und mich dagegen entschieden.

Ein Excel-Dokument sollte sich schon mit Bordmittelchen in einen gewünschten Pfad per Latebinding speichern lassen?

Das mit Speichern, Verschieben und erneut Öffnen habe ich mir auch schon als letzte Möglichkeit ausgeguckt. Das wäre wirklich krass, zumal es dort dann auch Rechteeinschränkungen geben könnte und es länger dauert.

Vielen Dank, dass Du es Dir ansiehst - Das ist wirklich absolute Spitze 👍

22.09.2015 - 13:09 Uhr

Hallo Jamikus!

Es wird der komplette Pfad mit Dateiname übergeben: z. B. C:\Users\mgrauber.MyDomain\AppData\Local\Temp\MyProg\Tabelle.xlsx

Auch z.B. "C:\Test\Tabelle.xlsx" funktioniert nicht. "Tabelle.xlsx" hingegen schon - dort wird aber nicht in meinen gewünschten Ordner hineingespeichert.

Excel möchte scheinbar nur einen Dateinamen haben. Daher beim Speichern die Fehlermeldung nicht länger als 218 Zeichen. - Das ist für einen langen Dateinamen, der in vielen Unterordnern steckt, viel zu kurz aber nah an der Grenze der Länge, die ein Dateiname unter dem Filesystem haben darf.

Grüße

22.09.2015 - 11:56 Uhr

Hallo!

Arbeitet wirklich niemand mit Excel, der etwas dazu sagen könnte? 🙁

Es soll wie gesagt unter verschiedenen Excel-Versionen laufen.

Danke im Voraus!!!!

17.09.2015 - 13:13 Uhr

Hallo!

Ich verwende für die Excel-Automation Latebinding und das soll sich auch nicht ändern.

SaveAs funktioniert so weit, ausser wenn ich einen kompletten Pfad übergebe. Dann erhalte ich folgende Fehlermeldung:

Fehlermeldung:
Auf die Datei konnte nicht zugegriffen werden. Versuchen Sie die folgenden Lösungsvorschläge:\n\n• Überprüfen Sie, ob der angegebene Ordner vorhanden ist.\n• Stellen Sie sicher, dass der Ordner, in dem sich die Datei befindet, nicht schreibgeschützt ist.\n• Vergewissern Sie sich, dass der Dateiname keines der folgenden Zeichen enthält: < > ? [ ] : | oder *\n• Der Dateiname darf nicht länger als 218 Zeichen sein.

Hier z.B. wird das Thema besprochen, aber nicht so richtig gelöst: http://stackoverflow.com/questions/7632081/getting-error-on-calling-saveas-method

Der Pfad ist nicht länger als diese 218 Zeichen, aber er enthält einen ":" vom "C:&quot;. Im Programm kann der Benutzer den Wunschpfad angeben. Eingetragen ist z. B. C:\Users\mgrauber.MyDomain\AppData\Local\Temp\MyProg\Tabelle.xlsx

Wenn ich versuche, den Application.DefaultFilePath bereits vor dem Speichern zu setzen und dafür beim Speichern wegzulassen, kann ich zwar den DefaultFilePath setzen, der wird aber beim Speichern unhöflicherweise ignoriert.

Warum ärgert mich Excel so und wie kann ich die Excel-Datei auch in einem anderen Ordner speichern?

Natürlich wäre es gut, auch mehr als einen 218 Zeichen langen Dateipfad+Dateinamen zu verwenden, da ich ja nicht weiß, welchen Pfad der Kunde einstellt.

Beim SaveAs versuchte ich bereits die Variante mit 2 Parametern (Pfad+Dateiname, 51) und mit den vielen Parametern.

Bitte um Hilfe! 🙁

17.09.2015 - 09:07 Uhr

Hallo Parso und Hallo Thomas!

Danke vielmals für die Lösungsansätze! 👍 👍

Ich bin erst jetzt vom Kunden zurück. Inzwischen habe ich es durchgeboxt, daß nun doch die Root-Werte in die DB eingefügt werden dürfen. Ich ändere daher die IDs der derzeit ersten Einträge direkt in der Datenbank. Gut das das nun doch klappt, ansonsten müsste ich die anderen Lösungswege gehen.

Schöne Grüße!

10.09.2015 - 12:06 Uhr

Hallo,

über ein hierarchical WPF-Treeview...

(IEnumerable<HierarchyNode<TEntity>> CreateHierarchy<...)

...werden alle Werte mit 0 bzw. leerer Guid immer direkt "als erstes" angezeigt. Es gibt daher mehrere Root-Werte:

+Eintrag1 (ID=0 bzw. Guid=leer)
+Eintrag 1a (ID=1 bzw. Guid=73932...)
+Eintrag2 (ID=0 bzw. Guid=leer)

die ID bzw. Guid-Werte kommen aus einer Tabelle und können dort nicht verändert werden. Für Eintrag1 und Eintrag2 ist das (ID=0 bzw. Guid=leer).

Es soll aber nun ein übergeordnetes Root-Node angezeigt werden und erst daran die beiden Einträge mit der ID=0 bzw. leeren Guid:

+Root-Eintrag
+Eintrag1 (ID=0 bzw. Guid=leer)
+Eintrag 1a (ID=1 bzw. Guid=73932...)
+Eintrag2 (ID=0 bzw. Guid=leer)

Wenn ich nun in meine ObservableCollection, die die zwei Einträge enthält einen weiteren Eintrag "Root-Eintrag" mit ID=0 bzw. Guid=leer einfüge, wird es auf der gleichen Ebene angezeigt wie Eintrag1 und Eintrag2.

  • Gibt es beim Treeview eine Möglichkeit den Root-Eintrag sichtbar zu machen (z. B. Treeview.ShowRootNode=true, ohne dass ich die ID bzw. Guid-Werte aller Einträge in der Tabelle ändern muss? (- was ich leider nicht darf)

Null funktioniert als ID bzw. Guid leider nicht.

Direkt nachdem die Werte in das Treeview gefüllt werden, ist ja nichts ausgewählt. Dieses "Nichts" könnte evtl. sichtbar gemacht werden?

🤔

Danke!

04.09.2015 - 11:10 Uhr

Hallo Witte und Abt!

Danke für die freundliche Hilfe! 👍 👍 Jetzt hab ichs verstanden: Bei der Standard SBS-Version ist nur ein "interner SQL-Server" für das benötigte SharePoint dabei. Daher muss ich dort die Express-Version oder einen vollen SQL-Server installieren. Und wenn es um das Anlegen einer neuen Instanz unter dem bereits voll installierten SQL-Server geht, so ist der Weg von Witte der passende.

03.09.2015 - 14:27 Uhr

verwendetes Datenbanksystem: <SQL-Server 2008R2>

Hallo!

Ein Kunde hat ein 2008er SBS Server laufen und darauf ist ein SQL Server Management Studio installiert über das ich (hier direkt am Server) mehrere SharePoint-Datenbanken sehe.

Ich möchte auf dem SQL-Server eine eigene DB erstellen. In der SharePoint-DB geht das nicht. Als Alternative kann ich mich nur mit dem SQL-Server Compact verbinden, welchen ich nicht nutzen möchte.

  • Für was ist diese "FILESERVER\SHAREPOINT"-Instanz zuständig? Der Admin wußte das auch nicht.

  • Ich habe auch als "FILESERVER\Administrator" keinen Zugriff, etwas an den DB-Einstellungen dieser SharePoint-Instanz zu ändern.

  • Wahrscheinlich ist es auch nicht gut, in dieser SharePoint-Instanz herumzuspielen und eine eigene Datenbank da hineinzulegen? Ich möchte nur eine eigene DB auf dem Server anlegen. Wie klappt das?

  • Wie sehe ich, ob es sich um einen richtig installierten SQL-Server handelt
    oder nur eine interne Verwaltungsdatenbank von Microsoft?

  • Beim Verbinden im SQL Server Management Studio habe ich auch versucht mich mit dem Servernamen direkt zu verbinden. Dort kommt nur eine Fehlermeldung "Es kann keine Verbindung mit 'FILESERVER' hergestellt werden. Gleiches gilt für FILESERVER\SQLExpress.

  • Müsste ich notfalls einen SQL-Server Express noch darüber installieren und falls ja, beeinflusst er die bereits vorhandenen SharePoint-Instanz bzw. DB nicht?

Ich kenne bislang nur direkt installierte SQL-Server und Express-Versionen. Was ist das hier?

  • "In Windows SBS 2011 Standard fungiert SQL Server 2008 R2 Express als Datenverwaltungssystem für die interne Unternehmenswebsite sowie für alle anderen Websites, die mit SharePoint Foundation 2010 erstellt werden" --> Bedeutet das, dass der scheinbar vorinstallierte SQL-Server für andere Datenbanken überhaupt nicht genutzt werden kann?

Danke

06.07.2015 - 15:52 Uhr

Hallo Abt und Alf!

Danke nochmals für die guten Informationen und auch den Link zum Artikel! Habe inzwischen viel mit dem Latebinding gemacht und werde auch aus diesem Grund erst einmal dabei bleiben.

Ich lasse den Fall erst einmal offen, weil sich evtl. ein kleines Problem abzeichnet.

Schöne Grüße!

02.07.2015 - 16:37 Uhr

Dankeschön für die so zahlreichen Antworten!

Ich habe mich nun für das Late Binding entschieden, da ich nicht schon wieder ein Fremdtool nutzen möchte.

Hier aber noch einige Fragen, die evtl. jemand beantworten kann:

• Was ist, wenn die eigene C# Anwendung auf einem Windows-Tablet (mit Tastatur) installiert wird und dort nur das „Outlook RT“ installiert wurde.
-> Funktioniert die Automation per Late Binding dann trotzdem? - Ich habe leider kein Tablet zum Testen.

  • Wenn die eigene C# Anwendung als 32bit kompiliert wird, sollte Office 32 Bit unterstützt werden, wenn sie 64bit kompiliert wird, sollte auch das Office 64 Bit unterstützt werden. Alles am besten in einem einzigen Code. Der Kunde setzt dann je nach dem entweder die 32 Bit oder die 64 Bit Version ein.
    -> Ich habe gerade auf dem Entwicklungsrechner nur ein Office32-Bit installiert. Ich müsste demnach die Methoden noch für 64 Bit anpassen?

  • Mit einer anderen Entwicklungsumgebung hatte ich bei der Automation Probleme (allerdings erst ab Office 2010; alle Office-Vorversionen funktionieren einwandfrei), wenn ich das Word-Dokument per Automation geöffnet habe, es vom Benutzer bearbeitet wurde und ich die Verbindung zum Word bis zum Schließen gehalten habe, um nach dem Schließen von Word wieder in mein Programm zurück zu gelangen und weiteren Code abzuarbeiten. Sporadisch riss dort manchmal die Verbindung ab obwohl das Dokument noch offen war – wahrscheinlich weil Word irgendwelche Ressourcen aufgeräumt hat. Habt Ihr solche Probleme ebenfalls – evtl. auch erst nach längerer Zeit oder einem Rechner Standby?
    -> Ist Euch so etwas schon mal mit Late Binding passiert oder muss ich mir da keine Gedanken machen?

Dankesehr!

01.07.2015 - 11:56 Uhr

Hallo Abt!

Danke. Habe ich gelesen - aber damit kann ich Dokumente auch ohne Benutzereingriffe manipulieren, wenn die C# Anwendung z. B. auf dem Server liegt.

Ich möchte aber während der Benutzer an einem Dokument arbeitet, auf die Word/Excel/Outlook - Instanz einen Zugriff haben und interagieren. Ich hatte dies etwas im Punkt "Word geöffnet lassen und das Schließen abfangen" beschzieben.

Es geht mir also primär nicht nur um das Verändern von Dokumentenihnalten, sondern die Fernsteuerung von Word/Excel/Outlook aus C# heraus. Das das über OpenXML möglich ist, habe ich noch nirgend wo gelesen - Gibt's dazu einen guten Artikel, wenn es so ist?

Wäre dann OpenXML die zukunftsfähige Technik um die beschriebenen Punkte umzusetzen?

Dankesehr!

01.07.2015 - 11:17 Uhr

Word, Excel und eventuell später Outlook sollen aus einer C# WPF Anwendung ferngesteuert werden (Öffnen, Text/Objekte einfügen, das Schließen des Dokuments durch den Benutzer abfangen etc.) und ich habe keine so richtig aktuellen und themenübergreifende Infos dazu gefunden (auch hier ist eine detaillierte Info von Rainbird noch aus dem Jahr 2006).

Es soll dazu kein Zusatztool/Zusatzcontrol verwendet werden.

  • Welcher Weg ist bei der Automation der neuste Stand der Technik?

  • Welchen Weg geht Microsoft in absehbarer Zukunft? Wird es eine andere Technik dafür geben oder wird die Automation evtl. sogar irgendwann eingestellt, weil man sich nur noch hauptsächlich um die Belange der Privatpersonen kümmert?

  • Verschiedene Word/Excel/Office Versionen sollten unterstützt werden:

• Gibt es Code, der bei allen Word/Excel/Office-Versionen 2010/2013 läuft (und evtl. auch in den Folgeversionen lauffähig bleiben wird – ja, sicher weiß das natürlich niemand.)?

• Was ist, wenn die eigene C# Anwendung auf einem Windows-Tablet (mit Tastatur) installiert wird und dort nur das „Outlook RT“ installiert wurde. Funktioniert die Automation dann trotzdem?

• Ich habe mich auch etwas über „Late Binding“ informiert (kein IntelliSense-Unterstützung beim Programmieren, keine Syntax-Prüfung beim Kompilieren, keine eingebauten Konstanten nutzbar). Sollte man diesen Weg gehen, damit man alle Word/Excel/Outlook-Versionen unterstützt?

  • Wenn die eigene C# Anwendung als 32bit kompiliert wird, sollte Office 32 Bit unterstützt werden, wenn sie 64bit kompiliert wird, sollte auch das Office 64 Bit unterstützt werden. Alles am besten in einem einzigen Code. Der Kunde setzt dann je nach dem entweder die 32 Bit oder die 64 Bit Version ein.

  • Wie testet ihr den Code dann 32/64bit auf unterschiedlichen Office-Versionen? – Theoretisch müsste man für jede Kombination auf einen Rechner installieren und dazu noch das VS, um den Code anzupassen? Das ist doch sehr aufwendig? – Es soll aber trotzdem ohne Fremd-Control gemacht werden.

  • Mit einer anderen Entwicklungsumgebung hatte ich bei der Automation Probleme (allerdings erst ab Office 2010; alle Office-Vorversionen funktionieren einwandfrei), wenn ich das Word-Dokument per Automation geöffnet habe, es vom Benutzer bearbeitet wurde und ich die Verbindung zum Word bis zum Schließen gehalten habe, um nach dem Schließen von Word wieder in mein Programm zurück zu gelangen und weiteren Code abzuarbeiten. Sporadisch riss dort manchmal die Verbindung ab obwohl das Dokument noch offen war – wahrscheinlich weil Word irgendwelche Ressourcen aufgeräumt hat. Habt Ihr solche Probleme ebenfalls – evtl. auch erst nach längerer Zeit oder einem Rechner Standby?

>>>>>>>> Mit welchem Weg der all das obere abdeckt kann man am besten arbeiten? Gibt es irgendwo Codesnippets/eine einfache und sehr ausführliche gesamtheitliche Info dazu?

Dankesehr!

14.07.2014 - 13:47 Uhr

Da es hier scheinbar keine Lösung gibt, wird die Datenbank mit den Grundtabellen etc. nun ausgeliefert und manuell importiert.

Damit ist das Thema geschlossen. Danke für die Hilfe.

10.07.2014 - 14:52 Uhr

Hallo Abt!

Entschuldige! Die neuste derzeit installierbare EF-Version ist die 6.1.1, wobei ich ein Update vom EF 5.0 gemacht habe. Gearbeitet wird mit ObjectContext.
Was noch auffällt: Evtl. wurde in diesem Zuge auch das .NET Framework 4 auf 4.5 geändert. - Leider nicht ganz nachvollziehbar, da wir immer nur Sicherungen der letzten Stände haben und die Datenbank bereits länger nicht mehr angelegt hatten.

Es sind wirklich nur die beiden Einzeiler, wobei in der 2. Zeile dann der erwähnte Fehler auftritt:

mydataentities.ExecuteStoreCommand("USE master");
mydataentities.ExecuteStoreCommand("CREATE DATABASE test");

Auch IMPLICIT_TRANSACTIONS vorher abzusetzen, bringt nichts.

USING(TransactionScope... wird nicht genutzt. Die Befehle werden einfach ausgeführt.

Habe zudem festgestellt, dass auch wenn die Datenbank per Hand in der Management Console angelegt wird, die restlichen Folgebefehle (einzeln nacheinander abgesetzt) die die Datenbank betreffen, z. B. SET ... in der Datenbank auch nicht ausgeführt werden. Die Tabellen, Felder und Indizes können aber problemlos angelegt werden, wenn man zuvor die Datenbank händisch in der Management-Console angelegt hat.

Ein Wechsel in die DB mit "USE" ist ebenso möglich. Habe aber wie auch in der bestehenden Datenbank volle Berechtigung.

Versucht auch als sa und mit Windows-Authentifizierung. Auch bei diesen Anmeldungen zusätzlich weitere Rechte in der MMC vergeben. Ebenfalls kein Erfolg.

  • Alle weiteren Einstellungen der neu erstellten Datenbank sind mit der bereits bestehenden Datenbank identisch. (Bis auf den Namen)

  • Auch "Handling of transaction commit failures" in der von Dir geposteten Seite bringt mich nicht weiter. Evtl. hat es etwas mit dieser Änderung daran zu tun?

Nur die Datenbank kann also nicht neu erstellt werden und Datenbankeinstellungen können nicht per ALTER DATABASE abgesetzt werden. Alles andere funktioniert.

Früher hat es wie gesagt 1a funktioniert. Am Code wurde nichts geändert.

Bitte nochmals sehr um Hilfe! 🙁 🙁

Grüße

10.07.2014 - 14:02 Uhr

Hallo Abt!

über die Suche bin ich auch auf SET IMPLICIT_TRANSACTIONS gekommen. Leider bringt das auch nichts.

Ich verbinde mich zuerst mit der master-Datenbank und setze dann direkt den CREATE DATABASE ab. Teilweise setze ich vorher IMPLICIT_TRANSACTIONS. Sonst mache ich nichts weiter. Trotzdem der Fehler beim Erstellen der Datenbank.
Auch führe ich diese Befehle einzeln und nicht zusammen aus.

Bisher ist es genau so gelaufen. Es wurde daran nichts geändert und mit einem Mal führt es zu dem Problem.

Was ist das?

Danke!

10.07.2014 - 10:55 Uhr

verwendetes Datenbanksystem: <SQL-Server 2010>

Hallo!

Bisher wurde mit ExecuteStoreCommand ein CREATE DATABASE - Befehl problemlos abgesetzt.

Seit der neuen Entity Framework-Version, klappt das auf einmal nicht mehr (Code wurde nicht geändert).

Es wird der Fehler "Die CREATE DATABASE-Anweisung ist in einer Transaktion mit mehreren Anweisungen nicht zulässig." angezeigt.

  • Es wird vorher nur mit USE master die Master-Datenbank geöffnet. Sonst nichts weiter.

  • Alternativ bereits vorher probiert SET IMPLICIT_TRANSACTIONS OFF. Bringt auch nichts.

  • Rechte sind auch vorhanden, es ist kein weiterer Befehl angehangen.

Arbeite mit DatabaseFirst-Ansatz.

Was hat sich da geändert?

Auch hier steht nichts genauer beschrieben: Fehler beim Erstellen einer Datenbank

Danke

26.03.2014 - 11:24 Uhr

Hallo LatinChriz!

Wieder einmal vielen Dank für die Hilfe! 👍

empfehle ich dir einfach mal das Model von der Datenbank upzudaten und davor ev. das Model selbst zu leeren damit es Konsistent mit der Datenbank ist

--> Ich habe schon alles versucht: über Kontextmenü "Aktualisieren", eine einzelne Tabelle zu entfernen und wieder einzufügen, Alle Tabellen aus dem grafischen Designer gelöscht, Programm bereinigt dann neu gestartet und alle Tabellen wieder hinzugefügt (und dabei die Anordnung aller Tabellen im Designer verloren) Alles ohne Erfolg. Gleiche Fehlermeldung.

1.) Auch sind die Annotations nicht drinnen, was aber verständlich ist, da die ältere Datenbank sich a) NICHT an die normierte Feldbeschreibung hält und b) die Keyspalten vom Typ GUID sind - was aber nach einigen Webseiten kein Problem bedeuten sollte. Jedoch werden im grafischen Designer die Schlüsselspalten mit einem Schlüsselsymbol korrekt markiert.

Daher habe ich die Zuweisungen per FluentAPI gemacht.

2.) Ja der EDMX-Designer würde alle Annotations nach einer Änderung entfernen. Daher nutze ich Fluent API und da die DbContext Klasse partial ist, mache ich das in meinen eigenen Dateien. Du schreibst "[Key]" statt Haskey. [Key] ist aber der andere Weg über Dataannotations.

3.) Siehe Zitat oben, alles schon versucht

4.) Da die Datenbank schon älter ist und "draußen" existiert und einige DBA's sehr eigen sind, würde ich schon gerne beim DatabaseFirst Ansatz bleiben.

Was ich halt nicht verstehe ist, dass es bei ObjectContext alles vom Designer automatisch gemacht wurde (Key und Beziehungen) und nun nach dem Update auf EF 6.1 nicht mehr.

Vielleicht noch irgendwelche Tipps?

P.S. Die Fettschreibung hatte ich zur besseren Übersicht gewählt, es sollte nicht als "schreien" aufgefasst werden.

Danke

26.03.2014 - 10:52 Uhr

Hallo Witte!

Nein. Da ich vom ObjectContext komme, habe ich noch keine einzige Migration über Nuget gemacht und es gibt dafür auch keine CS-Files.

Es existiert nur die grafische EDMX-Datei, die die Entitätsklassen unter sich erstellt hat. Allerdings nur die einzelnen Felder ohne die Annotations. Das ist ja eigentlich auch der richtige Ansatz, da ich derzeit nicht CodeFirst nutze und auch nicht möchte.

Grüße

25.03.2014 - 17:02 Uhr

verwendetes Datenbanksystem: <SQL-Server 2012>

Hallo!

Ich bin noch an der Umstellung von EF 5 + Object-Context + Database First nach EF 6 + DbContext + Database First.

Ich nutze den EDMX-Designer und "Entity Framework 6.0.2 Tools for Visual Studio 2012" sind installiert.

Inzwischen habe ich mich sehr in das EF 6 eingearbeitet, habe aber folgendes Problem, da meist nur EF6+CodeFirst beschrieben wird, ich aber vorerst bei DataBase First bleiben möchte.

Bei ObjectContext unter EF5 hat der EDMX-Designer immer alle Key-Annotations plus alle Beziehungen selbst erstellt. Das macht er jetzt nicht mehr, sondern legt nur noch die nakten Entity-Klassen an. Im EDMX-Designer zeigt er aber trotzdem bei den Schlüsselspalten ein Bild mit einem Key davor.

  1. Ist das ein Fehler im Designer oder muss ich nun diese Sachen selbst machen, obwohl ich DatabaseFirst nutzen möchte und alle Keys und Beziehungen in der Datenbank bereits vorhanden sind?

Falls ich sie selbst machen muss, habe ich mich für Fluent API (statt DataAnnotations) entschieden: Mit HasKey den Schlüssel für alle Entitäten festgelegt und mit HasRequired die Tabellenbeziehungen.

Leider kommt nun noch beim 1. Ausführen des 1. Linq-Befehls folgender Fehler:

Das Unterstützungsmodell des Kontexts 'MyEntities' wurde seit der Erstellung der Datenbank geändert. Sie können Code First-Migrationen verwenden, um die Datenbank zu aktualisieren (
>
).

So und jetzt bin ich wieder auf der Webseite vom Anfang. Er möchte unbedingt den Codefirst-Ansatz und sagt mir nicht, wo genau der Fehler liegt!

Brisant dabei: In der Linq-Abfrage wird eine Tabelle abgefragt, die nur einen Key, aber keine Beziehung hat und der Key wurde mit HasKey ordentlich definiert.

Ich habe im EDMX-Designer bereits eine Validierung und Aktualisierung durchgeführt, jedoch ohne diesen Fehler wegzubekommen.

  1. Es scheint irgend etwas in der Datenbank und im Model noch anders zu sein. Nur wie finde ich es heraus was genau das ist?

  2. Sollte ich vielleicht den EDMX-Designer zukünftig nicht mehr benutzen und komplett auf den CodeFirst-Ansatz umswitchen? Achtung: Die Tabellenerstellung und Updatefunktion habe ich derzeit in einem Updateprogramm durch SQL-Befehle geregelt. Das sollte, wenn möglich, auch zukünftig weiter genutzt werden - statt dem CodeFirst-Tabellen-Updateprozess (obwohl dieser relativ stimmig erscheint).

Vielen Dank für Eure Hilfe!

25.03.2014 - 16:21 Uhr

Hallo Palin!

der Link und die Unterlinks waren sehr gut und ich habe sogar das Testprojekt umgesetzt.

Allerdings wurden diese Entitäten bereits durch den EDMX-Designer korrekt erzeugt.

Das Problem war, dass der Connectionstring zwar richtig war, aber zuerst initialisiert und dann der .ConnectionString gesetzt wurde. Bei ObjectContext war das bisher kein Problem, nur DbContext will es direkt im Konstruktor haben.

Also läuft die Connection ersteinmal!

Nochmals Danke an alle! 👍 👍 👍

20.03.2014 - 16:00 Uhr

Hallo Abt!

Ich verstehe, das Du keine Lösung vorkauen möchtest und ich selbst darauf kommen muss. Bitte verstehe auch mich: Ich bin seit einer Woche an der Umstellung von ObjectContext auf DBContext und mit dem übernommenen Code wirklich am verzweifeln. Zudem habe ich auch ein Zeitproblem, da ich nicht damit gerechnet habe, dass das Update von EF 5 auf EF 6 so aufwendig ist.

Zuersteinmal zurück zu EF 5 will ich nach der Woche aber leider auch nicht, da ich so extrem viel Arbeit hineingesteckt habe.

Ich bin froh über jede Hilfe, da ich weiß, das ihr das freiwillig macht. Dafür Hut ab! 👍 👍 👍

Ich habe im letzten Eintrag meine Fortschritte geschrieben und hoffe, Du kannst mich nochmals bei der Entscheidung unterstützen.

Ich schwöre Dir, der untere Code steht bei mir in der automatisch generierten "MyModel.Context.cs"-Datei (also erst wenn man die TT-Datei aufklappt); nicht jedoch in der MyModel.Context.tt-Datei (diese beginnt mit einem "<#") und auch nicht in der MyModel.Designer.cs-Datei (die nur einen Kommentar enthält):


public partial class MyEntities : DbContext
     {
         public MyEntities()
             : base("name=MyEntities")
         {
         }
         ..... 

Aber vielleicht hast Du das ja gemeint mit TT-Datei, da sie darunter angezeigt wird?

a) muss man wissen, was sie tun und b) muss man wissen, wie der generierte Inhalt anzusprechen ist. Beide ist bei Dir wohl eher nicht der Fall.

Da gebe ich Dir allerdings Recht. Ich versuche mich aber damit zu beschäftigen. Nun schon seit einer Woche.

Du kannst problemlos den generierten Context links liegen lassen und eine eigene Klasse erstellen, die von DbContext erbt und die nutzen - nach Deinen wünschen. Wo ist das Problem?

--> Das ist ein sehr guter Hinweis. Wenn ich wirklich den grafischen Designer ignoriere und alles per Hand codiere.

Momentan steht in der MyModel.Context.cs (unterhalb der MyModel.Context.tt) u. a. folgendes:


         protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            throw new UnintentionalCodeFirstException();
        }
    
        public virtual DbSet<Kunde> Kunde { get; set; }
        public virtual DbSet<Lieferant> Lieferant { get; set; }
        ...

--> Ich müsste faktisch nur die obere OnModelCreating-Methode füllen sowie bei jedem Einfügen einer neuen Tabelle das DbSet unten ergänzen.

  • Kannst Du einen Link empfehlen, wo das richtig gut erklärt wird? Ich würde mich da gerne - trotz Zeitmangel - richtig einarbeiten.

Besten Dank!

20.03.2014 - 15:40 Uhr

Hallo Palin und Abt!

Vergleich mal deinen ConectionString mit den vom EF erzeugten.

Super und erst einmal vielen Dank! 👍 👍 👍 Damit führtest Du mich bereits weiter in Richtung Lösung! Die vom EF erzeugten steht in der app.config. --> Und die Fehlermeldung besagte ja: "Der Eintrag &quot;MyEntities&quot; wurde bereits hinzugefügt."

Das brachte mich auf die Idee, in der app.config den Abschnitt, wo die Verbindungszeichenfolge gespeichert wird auszudokumentieren. Also alles im Bereich "<connectionStrings>". Und siehe da: Das Programm öffnet nun korrekt die Connection! 👍 👍 👍

Folgendes wurde automatisch eingefügt:


protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            throw new UnintentionalCodeFirstException();
        }

Nun läuft das Programm schon einmal los.

Aber schon bei der ersten Abfrage von der Datenbank kommt nun folgender Fehler:

„Code, der mit den T4-Vorlagen für die Database First- und Model First-Entwicklung generiert wurde, funktioniert im Code First-Modus möglicherweise nicht ordnungsgemäß. Wenn Sie weiterhin 'Database First' bzw. 'Model First' verwenden möchten, stellen Sie sicher, dass die Entity Framework-Verbindungszeichenfolge in der config-Datei der ausführenden Anwendung angegeben ist. Um die mit 'Database First' oder 'Model First' generierten Klassen im Code First-Modus zu verwenden, fügen Sie eine ggf. erforderliche Zusatzkonfiguration mithilfe von Attributen oder der DbModelBuilder-API hinzu, und entfernen Sie dann den Code, der diese Ausnahme auslöst.“

>> Klar, weil ich ja vom DB-First her komme.

Ich würde wahrscheinlich auf "Code First with an existing database" gehen

Und dadurch steht erneut eine Grundsatzentscheidung an:

Ist nun "data annotations" oder "fluent api" empfohlen?

Vielen Dank für Eure Hilfe!!!! 👍 👍 👍

19.03.2014 - 16:19 Uhr

Hallo LatinChriz!

Zuersteinmal auch an Dich vielen Dank! 👍

Ich habe mir wirklich Zeit genommen, komme aber noch immer nicht weiter. Du schreibst:

Falls du nun gerne einen Konstruktor hast dann musst du die Templatevorlage ändern - also die *.tt Files,
und diese werden bei jedem speichern/ändern vom Modell neu ausgeführt.

--> Abt sandte den Link, bei dem der Konstruktor überladen werden sollte. Dieser Abschnitt befindet sich bei mir aber in der MyModel.Context.cs - nicht jedoch im tt-File❔


   public partial class MyEntities : DbContext
    {
        public MyEntities()
            : base("name=MyEntities")
        {
        }
        .....

Wenn ich ihn nun wie im Beispiel angegeben erweitere, schreibe ich in der MyModel.Context.cs folgendes dazu:

public MyEntities(string connectionString) : base(connectionString)
{
Database.Connection.ConnectionString = connectionString;
}

Nun lässt sich meine Zeile


MyEntities myEntities = new MyEntities(entityBuilder.ToString());

zwar kompilieren aber löst eine Exception während der Ausführung aus:

Der Eintrag &quot;MyEntities&quot; wurde bereits hinzugefügt.

Übergebe ich sqlBuilder.ToString() geht es auch nicht. Da kommt die Meldung:

Schlüsselwort wird nicht unterstützt: 'data source'.

Theoretisch brauche ich auch die Überladung des Konstruktors im selbst generierten File wie oben angegeben ja gar nicht und könnte direkt folgendes angeben:


MyEntityConnection = new EntityConnection();
   MyEntityConnection.ConnectionString = entityBuilder.ToString();
// oder
   MyEntityConnection.ConnectionString = sqlBuilder.ToString();

Und das bringt mir aber leider natürlich die identischen Fehlermeldungen wie oben. Das Problem ist nicht die Überladung des Konstruktors, sondern das mein Connection-String nicht akzeptiert wird. Das Projekt wurde ja nur von ObjectContext auf DB-Context umgestellt.

Eine Erklärung könnte sein, dass beim DB-Context der Context ja bereits existiert und daher auch die Meldung kommt. Also scheint der entityBuilder.ToString()) zwar die richtige Wahl zu sein, wird jedoch vom T4-Template verhindert?

  • Ist das so?

  • Nur wie kann ich dann die Daten zur Laufzeit übergeben/ändern?

  • Einen ähnlichen Artikel wie Abt habe ich hier gefunden:

http://social.msdn.microsoft.com/Forums/en-US/deab3d98-c392-496a-a6ee-aa181157ebc6/passing-a-connectionstring-in-dbcontext-constructor?forum=adodotnetentityframework

Ich bin gerade wirklich am Verzweifeln! 🤔 🤔

Vielen Dank für Eure Mühe!!!

19.03.2014 - 11:09 Uhr

Hallo Abt!

Erst einmal besten Dank.

Du muss den Generator nicht nutzen!!!

Das heißt, ich soll den Generator nicht nutzen? Ich habe mir inzwischen ernsthaft überlegt, zurück zu gehen zu ObjectContext und dann den Code, den der Generator erstellt für die zukünftigen Tabellen manuell zu schreiben.

  • Das ist wahrscheinlich 1000 mal weniger Aufwand als die Umstellung auf DBContext.
  • Zudem brauche ich nicht immer die Tools vom Team zusätzlich installieren

1.) Nur wie lange kann ich so arbeiten? Wird der ObjectContext oder der direkte Zugriff darauf irgendwann abgeschafft? Oder wird er weiter bestehen? (DbContext ist ja eigentlich nur ein Wrapper darum)

Der Generator erzeugt Dir zwar die Klasse; aber Du kannst sie doch verändern, wie Du lustig bist.

---> Und genau das will ich nicht. Der Code wird ja jedes mal mit dem einfügen einer neuen Tabelle neu generiert. Alle Änderungen müsste ich dann immer erneut ausführen. Und es ist ja an sich nicht empfohlen, diese Dateien zu verändern.

Was auf Deiner Seite beschrieben wird habe ich nun versucht manuell zu machen:


  MyEntityConnection = new EntityConnection(sqlBuilder.ToString());

Das funktioniert derzeit trotzdem nicht, da Fehler "Schlüsselwort wird nicht unterstützt:" "data source".

sqlBuilder.ToString() enthält folgendes:

"Data Source=.;Initial Catalog=MyDB;Integrated Security=True;Pooling=False;MultipleActiveResultSets=True;Connect Timeout=6"

Übergebe ich den String aus Interesse einfach direkt und entferne "Data Source=.", bemängelt er das nächste Schlüsselwort "Initial Catalog".

Warum akzeptiert er nicht einmal mehr einfache Connectionstrings?

Momentan sehe ich leider nur noch rot, da mich diese Umstellung auf DBContext völlig aus der Bahn wirft. Bitte nochmals um Hilfe!!!!

19.03.2014 - 10:01 Uhr

Hallo!

Folgendes hat vor der Umstellung von Object-Context auf DB-Context einwandfrei geklappt:


MyEntityConnection = new EntityConnection(entityBuilder.ToString());
//... einige Schritte...
MyEntities myEntities = new MyEntities(MyEntityConnection);

Leider kann dem Konstruktor in der untersten Zeile nun keine EntityConnection übergeben werden, da nun der DB-Context das nicht mehr unterstützt. 🙄

Wie kann ich es ändern? (Da es hier sehr viel Beiwerk im Programmcode gibt, sollte "MyEntityConnection" unbedingt erhalten bleiben und weiterhin übergeben werden.)


MyEntityConnection = new EntityConnection();
//... einige Schritte...

// Nun ohne Parameter - funktioniert:
MyEntities myEntities = new MyEntities();

// Diese Zeile läuft natürlich nicht, wie kann ich die EntityConnection dann übergeben? Wie muss diese Zeile lauten:question:
myEntities.Configuration.Entity = MyEntityConnection;

Irgendwie muss ich nun in der letzten Zeile noch MyEntityConnection übergeben. "myEntities.Configuration.Entity" gibts natürlich nicht. Wie wird das dann gemacht?

Vielen Dank!!!!!