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

23.01.2012 - 15:06 Uhr

Hallo,

sobald parallel gearbeitet wird, kann es im Entity Framework zu einer Exception kommen, wenn der Datenleser bereits belegt ist (und mit der gleichen Verbindung gearbeitet wird - und das möchte ich nicht ändern). 🙁 Nun kann man diesem Problem scheinbar mit lock (Objekt) beikommen.

Da es sich mir aber eher sporadisch "präsentiert" und schwer zu testen ist, habe ich dazu einige Fragen:

  • Kann die Exception auch auftreten, wenn man zur gleichen Zeit mit verschieden (SQL-Server)-Tabellen bzw. Entitäten arbeitet? Liegt es also daran, das der Datenleser immer nur eine Operation zu einer Zeit durchführen kann - unabhängig von der Tabelle?

  • Kann die Exception auch auftreten, wenn gelesen wird und in einem anderen Thread gleichzeitig geschrieben wird bzw. umgekehrt?

  • Wenn .NET einen Lock-Block gerade abarbeitet, werden dann trotzdem "parallel" der Haupttask und die anderen Background-Threads weiter abgearbeitet oder friert das Programm so lange ein?

(Sollte es tatsächlich einfrieren, würde der Hintergrund-Task ja überhaupt keinen Sinn mehr machen) - Oder laufen vielmehr die weiteren Hintergrund-Tasks so lange "parallel" weiter, bis das gleiche Objekt gelockt wird?

  • Arbeitet .NET gerade einen Lock-Block ab und wird ein zweiter und ggf. noch ein dritter Lock-Block in dieser Zeit aufgerufen, stoppt .NET nur am zweiten und dritten Lock-Block solange, bis der erste Lock-Block fertig ist und setzt dann die Arbeit im zweiten Lock-Block fort und nach dessen Beendigung dann den dritten?

Vielen Dank!

28.12.2011 - 14:58 Uhr

Vielen Dank Herbivore,

schön, dass ich nicht ganz "Abseits" lag. Es klappt nun perfekt!

(Der Code wird tatsächlich nur 1x ausgeführt; der Debugger hatte aber im anderen Task aus irgend einem Grund nicht angeschlagen; mit einer Test-Messagebox ist der Ablauf aber gleich - Nun aber alles ok.)

Vielen Dank nochmals! 👍

Hallo Winsharp93,

auch Dir vielen Dank für den Tipp! 👍 - Das kannte ich auch noch nicht. Bei mir geht es jedoch nicht nur um ein einzelnes Objekt, welches ich locken möchte.

Grüße!

28.12.2011 - 13:54 Uhr

Hallo,

ich suche eine (bitte einfache) Möglichkeit, Programmcode én Block - also in einem Rutsch auszuführen. D.h. wenn parallele Tasks oder Backgroundworker zur gleichen Zeit laufen, soll der Block durchgearbeitet werden und erst am Ende mit den parallelen Tasks oder dem Backgroundworker fortfahren.

Natürlich sollte diese Möglichkeit auch in einem parallelem Task oder Backgroundworker funktionieren.

Am besten ohne irgendeine "Hilfsvariable", sondern als ".NET-Befehl"?

Wunsch wäre folgendes:



...normaler Programmcode

DoWithoutStop(
    int i;
    i++;
    i--;
)

...normaler Programmcode

Wenn es doch nur mit einer "Hilfsvariable" gehen sollte, wäre theoretisch der Lock-Befehl mit einer public static Variable für mich gangbar. Leider sagt Microsoft, dass diese Variable immer private sein sollte:

Vermeiden Sie es grundsätzlich, einen public-Typ zu sperren oder Instanzen, die nicht durch Ihren Code gesteuert werden. Die allgemeinen Konstrukte lock (this), lock (typeof (MyType)) und lock ("myLock") verstoßen gegen diese Richtlinie:

Für mich wäre es aber wichtig, dass dieses Locking im gesamten Programm funktioniert, daher "static public". Was wäre daran "anrüchig"?

Vielen Dank!

27.12.2011 - 14:42 Uhr

Hallo Talla,

vielen Dank, unter Deinem Link werden sehr gut die Vor- und Nachteile der unterschiedlichen Arten, Einstellungen zu speichern diskutiert. Problematisch wird es aber mit dem User-Ordner, wenn ich ein Programm mehrmals auf einem Rechner installieren will (z. B. Zugriff auf unterschliedliche Datenbanken - mit natürlich anderen Einstellungen). Hierzu werde ich aber bei Bedarf besser ein neues Thema aufmachen, um nicht offtopic zu gelangen.

Ja, der SoundPlayer tuts auch und ich bin sehr froh um diesen Tipp! 👍 Schade nur, dass er nicht alles kann, was der "große Bruder" MediaElement kann. (z. B. Lautstärke, und Zusammenarbeit mit Animation muss ich mir bei Bedarf später noch ansehen) Daher hätte ich gleich von Anfang an den "großen" genutzt.

Zudem mag ich nicht die Art, wie .NET mit eingebetteten Resourcen umgeht: Bei Bildern so, bei Sound so... Eine einheitliche Art und Weise wäre mir schlüssiger gewesen.

Dein Einwand ist korrekt. Es handelt sich aber ohnehin um 1-3 Mini-Audiodateien, die die Ressourcen nicht so sehr aufblasen und zumindest verhindere ich dadurch eine Ladeverzögerung.

Also nochmals Dir und Ersobar vielen Dank! 👍 👍

27.12.2011 - 12:37 Uhr

Hallo Ersobar und Talla,

ersteinmal vielen Dank für Eure Hilfe! 👍 👍

Ich "albere" nun schon eine ganze Zeit damit herum und war zuerst fest überzeugt, dass ich es einmal wieder nicht verstanden habe.

@Talla: Ja, die Exception hatte ich auch; Sie tritt aber nur auf, wenn man das Error-Handling explizit implementiert.

Die interessante Lösung von Ersobar mit der temporären Datei wäre ein erster Ansatz. Jedoch sollen relativ kurze Wav-Stücke öfters und an verschiedenen Stellen wiedergegeben werden. Dafür immer die Dateien anzulegen (in welchem Ordner - und unter welchen Zufallsnamen - auch immer) ist natürlich auch nicht die beste Lösung. Zumal könnte sie bei längeren Titeln auch einen Verzug der Wiedergabe bewirken.

Aber ich kenne auch kein professionelles .NET-Programm welches die benötigten Sounddateien in einem Ordner fest mitinstalliert. Das würde u. U. ja auch zu lizenzrechtlichen Problemen führen, wenn irgend jemand diese Sound-Dateien dann weiterverwendet und weiterhin zu Fehlern führen, wenn ein Benutzer diese Dateien löscht; auch wenn man die Existenz vorher prüft.

Microsoft sollte doch eine solche Möglichkeit geschaffen haben, Fremd-Dateien in die Applikation zu embedden. Evtl. kann man unter .NET (nur für den Speicherbereich des Programms) ja auch virtuelle Pfade anlegen und dann mappen? (Ähnlich einem früheren Ram-Drive)?

Ich bemerke aber schon wieder: Es wird mal wieder nicht so leicht.

Vielleicht hat ja noch jemand eine Idee?

Nachtrag @talla: Aber Microsoft geht doch wieder den Weg weg von der Registry dazu über, Programmeinstellungen in Dateien zu speichern (App.config) - darin speichere ich meine Connection-Einstellungen. Du würdest also in dieser Datei überhaupt keine weiteren (rechner- und nicht datenbankbezogenen) Programmeinstellungen speichern?

Vielen Dank!

27.12.2011 - 11:27 Uhr

Volltreffer!

Das war meine absolute Dummheit! - Entschuldige. Genau so ist es. Die Controls heißen nur leicht unterschiedlich und ich hatte das übersehen.

Achtung: Nutzt man die DependencyProperty nicht im XAML, kommt keine Fehlermeldung und man sucht den Fehler ewig. Somit habt Ihr mir geholfen, meine Dummheit über 4 Ecken zu entdecken!

P.S. Zukünftig poste ich die exakten Fehlermeldungen. Entschuldige dafür!

Tausend Dank und einen Guten Rutsch! 👍 👍

27.12.2011 - 11:13 Uhr

Hallo CSharperUser,

nochmals verspäteten Dank für Deine Antwort! 👍 So ähnlich hatte ich es gemacht und es hatte nicht funktioniert. Nun weiß ich aus einem anderen Grunde:

Ich weiß nun, warum mir .NET in XAML die Meldung präsentiert hat "Dependency Property wäre nicht registriert".

Bei "DependencyProperty.Register("Testprop"...." habe ich bisher teilweise noch den Namen des Usercontrols eingeflochten. Z. B. "MyControlTestprop", weshalb zwar die Property funktionierte, aber im XAML-Code nicht richtig angesprochen werden konnte.

Warum habe ich das gemacht❔
Wenn ich mehreren unterschiedlichen UserControls eine Property gebe "DependencyProperty.Register("Testprop"...." meckert .NET, dass diese Property bereits registriert sei. Daher hatte ich dem Propertyname den Namen des Usercontrols vorangestellt: "Usercontrol1Testprop" bzw. "Usercontrol2Testprop". -

Nur wie kann ich dann .NET davon abbringen, dass es mir bei 2 unterschiedlichen Controls verbietet eine Property gleich zu nennen? Beide Propertys haben doch nichts mit einander zu tun?

Vielen Dank!

22.12.2011 - 15:46 Uhr

Hallo,

ja, Resource auch. Bei Bildern funktioniert es ja mit Resource. Ich habe auch bereits "Eingebettete Resource" versucht, da es für mich sinnig erschien. Klappt leider alles nicht. 🙁

P.S. Nur wenn man auf "Inhalt" geht, sieht man in den Veröffentlichungs-Einstellungen -> Anwendungsdateien diese Datei. Seltsamerweise klappt es bei den Bildern (die auf Resource stehen) ja auch, wenn diese dort nicht aufgelistet sind.

22.12.2011 - 13:44 Uhr

Hallo,

ein MediaElement soll eine wav-Datei wiedergeben. Mit der Datei auf der Festplatte und der Absoluten Uri und absoluter Pfadangabe funktioniert es.

Nur soll die wav-Datei in die exe hineinkompiliert werden. Und dann läuft es nicht mehr. 😭 X( Daher habe ich bei der wav-Datei "Buildvorgng": "Keine" und "Inhalt" versucht sowie
"In Ausgabeverz. kop." "Nicht kopieren" und "Immer"

-> Welche Angabe ist hier richtig?

Die Uri des MediaElements kann meist korrekt zugewiesen werden, nur beim Play() passiert nichts bzw. im MediaElement.Source werden die Angaben in diesem Fall nur teilweise angezeigt.

Als Uri habe ich verschiedene Varianten z. B. "/MyApp;component/Musik/Musik.wav" und RelativeOrAbsolute angegeben.

-> Wie muss die Syntax der Uri lauten?

Bei Bildern klappt es doch auch. Gibt es bei Musikdateien irgendwelche Unterschiede?

Pack URIs in WPF von gfoidl habe ich auch bereits gelesen; hat mich aber nicht zum Ziel geführt.

Vielen Dank!

14.12.2011 - 15:01 Uhr

Hallo mg.net,

ersteinmal noch vielen Dank für Deine Antwort! 👍

Ich muss besser aufpassen: Bei mir war Dein Eintrag nicht mit "Neue Nachricht" angezeigt.

Ich sehe nun langsam, dass die Optimierung durch sehr viele unterschiedliche Parameter und Statistiken beeinflusst wird und daher nicht mit einfachen Schritten A- B- C bzw. "wenn dann sonst" umrissen werden kann. Deine Grundregeln sind dabei die wichtigsten.

Deine Antworten haben mich nun auf die richtige Fährte gebracht und ich muss es dann mit Echtdaten austesten und dann nochmals - falls es Zeitprobleme gibt - verschiedene Konstellationen testen und messen.

Nochmals vielen Dank für Deine Hilfe!

Eine schöne Vorweihnachtszeit!

Grüße!

14.12.2011 - 14:50 Uhr

Hallo Talla,

auch vielen Dank für Deine Info! 👍 Auch wenns nicht im XAML geht, danke ich Dir auch für Deine Antwort, da man sonst nie weiß, wie lange man suchen soll.

Das heißt, dass man scheinbar nur "einfache" Typen (wie Int, String) im XAML nutzen kann? DateTime scheint bereits schon nicht zu gehen, ich kenne jedenfalls nicht die notwendige Notation dafür.

Ja, mit String klappt die Vorgehensweise, aber ich dachte, dass es evtl. mit einem Kniff geht. Property="0" im XAML-Code wird ja auch korrekt in eine Zahl umgewandelt.

Grüße!

14.12.2011 - 14:44 Uhr

Hallo DaMoe,

das ist wirklich ein sehr interessanter Ansatz und müsste theoretisch funktionieren. 👍 Leider mosert .NET:

Fehlermeldung:
Binding kann nicht für die Eigenschaft Testprop vom Typ MyUserControl festgelegt werden. Binding kann nur für eine DependencyProperty eines DependencyObject festgelegt werden.

Seltsamerweise wird die DependencyProperty aber durch Intellisense im XAML-Code korrekt angezeigt und ändert man den Typ von UIElement auf String klappt es auch fehlerfrei. Nur scheinbar kann man doch wirklich kein UIElement im XAML übergeben und bei der Fehlermeldung stimmt der Text nicht so richtig.

Vielleicht liegt es auch daran, dass ich im UserControl Textbox1 mit x:Name="Textbox1" definieren musste und nun auf das x: nicht zugegriffen werden kann?

Das wäre schade, da ich es schon im XAML-Code einbauen wollte.

Grüße!

14.12.2011 - 11:46 Uhr

Hallo,

in einem eigenen Usercontrol erstelle ich eine Dependency Property (z. B. "Testprop") vom Typ UIElement.

Im XAML-Code wo das Usercontrol verwendet wird, setze ich Testprop="Textbox1". Textbox1 ist eine auf der Form vorhandene Textbox.

Problem:

Im XAML-Code kommt die Fehlermeldung, dass String nicht in UIElement konvertiert werden kann. .NET erkennt also im XAML-Code nicht, dass die Dependency Property vom Typ UIElement ist und nörgelt dann. Wie muss ich es ändern, dass das klappt? - Dieser Fehler wird nicht erst im Setter ausgelöst, sondern bereits im XAML-Form. X(

Vielen Dank!

05.12.2011 - 11:04 Uhr

Hallo,

an dieser Stelle hatte ich ein Problem, welches aufgetreten war, weil ich die Klasse, die per Binding und DataContext gebunden ist, danach erneut per LINQ ausgelesen habe.

Darf man so etwas grundsätzlich nicht tun? Es wurde dadurch das Binding gestört.

Vielen Dank!

Mit freundlichen Grüßen

05.12.2011 - 10:38 Uhr

Hallo mg.net und Gü,

ich war leider einige Tage krank, bin aber nun wieder auf den Beinen. 🙁 Eine Sache habe ich doch noch nicht so richtig herauslesen können:

Bei meinem Anfangs erwähnten Beispiel filtere ich in der Where-Bedingung z. B. 4 Felder in Tabelle A und 3 Felder in in Tabelle B. (Bedingungen sind meist mit AND-verknüpft, Tabelle A und B sind gejoint.)

Zur optimalen Geschwindigkeitsausnutzung muss ich daher für die 4 Felder in der Tabelle A einen gemeinsamen Index und für die 3 Felder in der Tabelle B einen weiteren gemeinsamen Index erstellen.

1.) Dadurch wird dann ein Tablescan vermieden? - obwohl es trotzdem zwei Indizes und nicht ein einziger Index ist?

2.) Aber einen tabellenübergreifenden Index, der Felder aus verschiedenen Tabellen beinhaltet gibt es ja zumindest beim SQL-Server nicht?

3.) Wenn ich einmal nach bestimmten Feldern (A,B,C) und dann mal nach anderen Feldern (A,B,E) filtern möchte, sollte ich also einmal einen Index mit A,B,C und einen weiteren Index mit A,B,E erstellen. Obwohl A, B redundant sind.

Ein Index A,B und Einzelindex C und Einzelindex E könnten auch zu einem Tablescan führen? - Weil eben kein direkter Eintrag gefunden werden kann.

Vielen Dank!

Mit freundlichen Grüßen

25.11.2011 - 16:05 Uhr

Hallo Gü,

hat bei mir mal wieder etwas länger gedauert, aber Deine Links sind einfach wirklich super! 👍 Vielen Dank!

Vieles davon ist zwar bekannt, jedoch die detaillierte Beschreibung des Index-Aufbaus habe ich so noch nicht gelesen!

Das sich in meinem Fall die Where-Bedingung auf zwei Tabellen bezieht, ist schon ein Geschwindigkeitsproblem. Den tatsächlichen Verlust werde ich aber erst bei voller Datenbank prüfen können.

Auf jeden Fall ein sehr lesenswerter Artikel, aus dem ich viel gelernt habe! 👍

Danke!

25.11.2011 - 10:26 Uhr

Hallo mg.net,

den langsameren Insert bzw. Update kenne ich auch von anderen Datenbanken. Da aber sehr viel mehr Daten abgefragt als erstellt und bearbeitet werden, ist dies bei mir nicht sehr schlimm. Zudem ist die Dauer wirklich sehr kurz, da nur ca. 1-40 Datensätze auf einmal eingefügt werden.

Bei einigen Datenbanken gibt es eine "physikalische Grenze" von Indizes. Wenn man mehr verwendet wird das System dadurch auch bei der Abfrage langsamer. Ich dachte nur, dass es so etwas ggf. auch beim SQL-Server gibt.

Also ersteinmal vielen Dank für Deine Infos 👍. Ich werde es ersteinmal umsetzen. Jetzt weiß ich wie.

Die Geschwindigkeitstests folgen dann mit den Daten.

Grüße!

24.11.2011 - 16:51 Uhr

Hallo mg.net,

vielen Dank für die schnelle Antwort! 👍 Das klingt sehr beruhigend 🙂

Gibt es Indizes, wenn ja: Sind diese verwendbar?

  • Ich würde für jedes Feld, wonach in der Filterbedingung gefiltert wird, einen Index erstellen (Gefiltert soll nach Int, Guid, DateTime und Bit werden). Gibt es für die Anzahl der Indizes geschwindigkeitsmäßig eine "Höchstgrenze", die man nicht überschreiten sollte?

  • Verknüpft wird nach Int bzw. Guid

Wie sieht der SQL-Befehl selbst aus (ein einfacher Join, oder - im extremsten Fall - ein cross join)

  • Es ist ein normaler Left-Join mit einer noch weiter einschränkenden Bedingung und noch ein weiterer Left-Join (aber ohne Bedingung).

Wie ist die Hardware bestückt, insbesondere: Arbeitsspeicher?
Was läuft sonst noch, gibt es eine bremsende Last auf dem System?

  • Das haben leider die Kunden in der Hand. Bei weniger Daten werden diese teilweise sogar mit der kostenlosen Express-Edition arbeiten und haben im schlimmsten Fall die SQL-Datenbank leider sogar lokal auf einer Maschine. 🙄

Diese Abfragen werden durchschnittlich ca. jede Minute auf normal 5 bis max. 40 Arbeitsplätzen gemacht werden und das System sollte die Daten schon sehr schnell darstellen. Daneben wird natürlich noch anders im Netzwerk gearbeitet.

Grüße!

24.11.2011 - 16:17 Uhr

verwendetes Datenbanksystem: <SQL-Server 2005-2008R2>

Hallo Datenbank-Experten,

In einer Tabelle A befinden sich sehr viele Datensätze (>100.000 - zukünftig evtl. auf 400.000 und darüber hinaus wachsend)

In einer Tabelle B befinden sich Kunden-ID´s (oder Guids).

A und B sind miteinander 1:n Verknüpft. D. h. Zu jedem Eintrag in Tabelle A gibt es mindestens 1 oder sogar bis zu 4 (im Extremfall bis zu 50) Kunden, die einem Eintrag in Tabelle A zugeordnet sind. (Somit sind in Tabelle B mind. gleichviel bis im Extremfall 50 mal so viele Einträge wie in Tabelle A.)

Wer weiß, wie sich der SQL-Server bei diesen Datenmengen geschwindigkeitsmäßig verhält, wenn in der Abfrage Where-Bedingung sowohl Bedingungen für Tabelle A als auch Bedingungen für Tabelle B gemischt werden. Der SQL-Server müsste dann ja für alle Datensätze intern die Verknüpfung bilden und dann per Where entscheiden, welche Daten zurückgegeben werden.

Normal frage ich meist nur eine größere Tabelle ab und meine Where-Bedingung bezieht sich nicht zusätzlich auf so riesige Zweittabellen.

Den größten Teil der Filterung kann ich in Tabelle A durchführen.

Vielen Dank!

24.11.2011 - 15:59 Uhr

Hallo Gü,

danke nochmals! Ich habe bereits einiges versucht. Jedoch ist das Problem, dass ich nicht von C# auf mein DataGrid zugreifen kann (weil jeder Datensatz ja unterschiedlich ein- und ausgeblendet sein kann) und sich das DataGrid so verhält, wie es die Daten vorgeben.

Durch Ändern eines Feldes in meiner Liste werden die Controls im "Datensatz"-Grids des DataGrids ein und ausgeblendet.

Ich müsste daher bereits im XAML-Code des DataGrids das "DGR_Border"-Element irgendwie zugänglich machen und die Height dann per Databinding festlegen. - Das klappt zumindest manuell in Snoop. Nur ich weiß nicht, wo und wie ich es einbauen kann: 🤔


<DataGrid.Columns>
    <DataGridTemplateColumn Header="Test">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                // <Border Name="DGR_Border" Height="{Binding Hoehe}"???...
                      <Grid... 

(Der Kommentar ist natürlich falsch und es ist sicher wieder einmal viiiiel komplexer...?) 🙁

Vielen Dank!

23.11.2011 - 16:02 Uhr

Hallo,

ersteinmal vielen Dank! 😁 Hat natürlich etwas gedauert.....................

Ich habe mich für Snoop entschieden. Geniales Tool 😁

Also der Bereich, der im DataGrid eigentlich Collapsed sein sollte, ist folgender:

DataGrid.Border.DG_ScrollViewer.Grid.PART_ScrollContentPresenter.ItemsPresenter.Part_RowsPresenter (DataGridRowsPresenter) und dort werden die DataGridRows der Liste gefunden. Ab hier wirds interessant:

DGR_Border (Border) ist irgendein automatisches Element, in dem mein Datagrid drinnen ist, welches ich pro Datensatz anzeige (dieses ist auch unter Snoop direkt darunter aufgelistet: "SelectiveScrollingGrid).

DGR_Border.Height=NaN
DGR_Border.SelectiveScrollingGrid.Height=NaN

Also sowohl das umgebende (automatische) Border-Objekt meines Grids als auch die Höhe meines Grids sind also lt. Prüfung korrekt gesetzt (NaN).

Nur, wenn ich die DGR_Border.Height auf 0 ändere, erreiche ich mein Ziel: dass die Zeile mit den Collapsed Objekten im Datagrid wirklich 0 statt einigen Pixeln hoch ist. Versuche ich, die Höhe der Objekte innerhalb der DGR_Border zu ändern, klappt es hingegen nicht. 🤔

Das scheint mir irgendein Bug zu sein? Aber wie komme ich an diese DGR_Border evtl. manuell per C# heran? Ich vermute, dass sind wieder tonnenweise Code. X(

Vielen Dank!

Grüße

23.11.2011 - 12:55 Uhr

Hallo,

mein DataGrid hat folgenden Aufbau:


<DataGrid.Columns>
    <DataGridTemplateColumn Header="Test">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <Grid...

Im Grid werden verschiedene Controls über die Visibility auf Visible oder Collapsed gestellt.

Alles klappt super, - zumindest fast alles 😦: Leider wird, wenn im Grid alle Elemente auf Collapsed stehen diese Row noch mit ca. 1 Pixel Höhe angezeigt. 🤔 Ich suche mich gerade tot, wo dieses Pixel herkommt. Margins und Paddings und Thicknesse´s sind überall auf 0, AutoGenerateColumns auf False, GridLinesVisibility auf None. Auch habe ich bereits versucht, die Höhe nicht auf Auto zu setzen, sondern zu binden. Ergebnis bleibt leider gleich.

Achtung: Das Pixel muss irgendwo außerhalb vom Grid liegen, da wenn das Grid gefärbt wird, dieser Bereich nicht mit gefärbt wird.

Weiß evtl. jemand woran das liegt? 🙁

Vielen Dank!

14.11.2011 - 14:43 Uhr

Hallo Gü,

Du hast mal wieder den Nagel auf den Kopf getroffen 👍 Das war genau das, was ich gesucht hatte!

Vielen Dank!

Grüße

14.11.2011 - 12:49 Uhr

Hallo,

im XAML-Code nutze ich einen Converter. Das ist etwas umständlich 😭:

  • per xmlns: den Namespace verfügbar machen
  • unter den Fenster-Ressourcen per Key ansprechbar machen
  • Converter dann zuweisen

Das klappt zwar, aber geht das auch ohne diese 3 Schritte? Ich würde gerne direkt bei "Converter=..." auf den Converter im C# Code verweisen.

Vielen Dank!

Grüße

11.11.2011 - 16:33 Uhr

Hallo Talla,

danke für den superschnellen Tipp! Das war das Stichwort! 👍 Bin gerade dabei, mich durch einige Ansätze zu arbeiten. Ist mal wieder nicht ganz so einfach wie gedacht.

Grüße

11.11.2011 - 13:53 Uhr

Hallo,

bitte nicht gleich googeln lassen, habe wirklich nichts passendes gefunden! 🙁

Eine ComboBox soll beim Aufklappen 2 Spalten haben. Dies mache ich mit einem ItemTemplate, darin DataTemplate und darin dann ein StackPanel. Und das klappt einwandfrei. - Überall finde ich nur diese Lösung. 🙁

Leider werden die 2 Spalten auch angezeigt, wenn die ComboBox geschlossen ist. Wie zeige ich in diesem Zustand nur den Wert aus einer bestimmten Spalte an? DisplayMemberPath verträgt sich leider nicht mit dem Template. 🤔

Ein knapper Code, am besten rein in XAML wäre natürlich am besten.

Vielen Dank!

11.11.2011 - 13:43 Uhr

Hallo Michael,

8o Wow! - dass ist ja wirklich heiß! 👍

Vielen Dank nochmals! Gehe nun auch über die Collection! Ist wirklich viel besser.

Grüße

07.11.2011 - 16:40 Uhr

Hallo Michael,

naja, die ObservableCollection mit den Einträgen bleibt ja dann die ganze Zeit zusätzlich im Speicher.

Die Schleife wäre bei mehreren Jahresangaben im Combo trotzdem notwendig um die Observable Collection zu füllen.

Aber im Prinzip hast Du schon recht. Und da ich ohnehin lieber nach einem gleichartigen Schema vorgehe, werde ich es wohl in das Binding an eine Liste ändern.

Vielen Dank nochmals! 👍

Gruß

07.11.2011 - 16:17 Uhr

Hallo Michael,

Danke! Ja, so mache ich es normalerweise auch. Manchmal - z. B. wenn im Combo einfach nur Jahreszahlen dargestellt werden, finde ich es aber als zu viel Overhead, noch eine Liste oder Observable Collection zu erstellen.

Ich dachte, es geht in diesem Fall sogar einfacher. Aber wenn Du mir schreibst, dass dies nicht so ist, hilft mir das auch weiter. 👍

Ich dachte nur, dass evtl. ein XAML-Binding wie SelectedValuePath="{Binding ComboBox.Content}" oder so ähnlich geht.

Evtl. hat ja noch jemand eine einfache Idee?

Gruß

07.11.2011 - 15:48 Uhr

Hallo,

normalerweise binde ich eine Combobox immer per Binding an eine Liste und das klappt auch. In einigen einfacheren Fällen möchte ich jedoch manuelle Werte mit Add hinzufügen. Wenn es sich nur um Werte (und nicht um ComboBoxItems) handelt, kann ich prima per SelectedValue= den Wert zuweisen.

Sobald ich Formatierung der Items benötige, muss ich ja z. B. ein ComboBoxItem hinzufügen. Hier habe ich aber das Problem, wenn ich das SelectedValue setzen will, klappt es nicht. (Es bleibt null und es ist nichts ausgewählt).


ComboBoxItem CItem = new ComboBoxItem();
CItem.Content="15";
CB.Items.Add(CItem);

Wie kann ich nun folgendes machen:


CB.SelectedValue="15";

Bitte nicht über SelectedIndex=0 o. ä. Ich möchte direkt den Wert setzen. Benötige ich dafür im XAML-Code noch ein SelectedValuePath="{Binding... oder ähnliches? X(

Vielen Dank!

17.10.2011 - 15:37 Uhr

Hallo Gü,

danke für die Information! 👍 Ich hatte noch immer etwas gesucht, was es ermöglicht. Leider findet man im Internet nur Sachen zum grafischen Model-Designer.

Aber für mich ist es sehr wichtig zu wissen, damit ich es umschiffen kann, statt weiter zu suchen.

Ja, der Neustart ist zwar nicht am elegantesten aber scheinbar wirklich die einzige Möglichkeit.

Vielleicht fügt Microsoft ja in der nächsten Version eine Refresh() - Möglichkeit hinzu. Das wäre prima!

Grüße nochmals!

17.10.2011 - 12:48 Uhr

verwendetes Datenbanksystem: <SQL-Server 2008>

Hallo,

mein Programm wird gestartet und läuft. Dann wird eine Änderung an der Tabellenstruktur gemacht (z.B. eine Tabelle 'Testtabelle' in der Datenbank angelegt)

(Diese Tabelle existiert bereits in der Model.edmx-Datei meines Programms)

Danach wird die Connection geschlossen und neu aufgebaut. Trotzdem meckert .NET anschließend, wenn man auf die neue Tabelle zugreifen möchte, obwohl die Tabelle da ist (sieht man auch im SQL-Server Management Studio):

Fehlermeldung:
Ungültiger Objektname 'Testtabelle'.

Startet man vor dem Zugriff auf die neue Tabelle hingegen das Programm neu, tritt kein Fehler auf.

Ich suche daher einen Befehl, ähnlich wie "dataentity.RefreshAllObjects" um den Neustart des Programms zu vermeiden.

Kennt jemand das Phänomen? 🤔

Vielen Dank!

Gruß

09.09.2011 - 10:20 Uhr

Hallo,

in einem WPF Programm funktioniert an einer Stelle ein Backgroundworker einwandfrei. Um den Programmcode zu verkürzen habe ich aus dem Backgroundworker einen BeginInvoke gemacht.

Beides läuft problemlos. Nur, wenn genau während des Hintergrundtasks ein Fenster verschoben wird, friert mir das komplette Windows(!) bei der BeginInvoke-Lösung ein. ⚠ (Nur durch Start des Taskmanagers - ohne beenden - kann wieder korrekt weitergearbeitet werden) Setze ich in die nächste Zeile hinter BeginInvoke eine Messagebox, wird diese aber korrekt angezeigt und das Programm friert nicht mehr ein.

Wie kann ich dieses Verhalten bei BeginInvoke vermeiden? 🤔

Ich vermute, dass ich mehrmals App.Current.BeginInvoke() verwende und dadurch der Dispatcher bereits belegt ist. Leider besitzt aber der Dispatcher keinen Konstruktor, dass ich mir für jeden BeginInvoke eine neue Instanz erstelle.

Ist BeginInvoke nur z. B. für einen Aufruf aus einem WPF-Fenster oder WPF-Objekt heraus gedacht? ?(

Vielen Dank!

Grüße

08.09.2011 - 14:07 Uhr

Hallo Gü,

👍 - Ohne Kommentar! Ja, ich habe mich wieder einmal so auf einen Weg versteift, dass ich die einfachste Lösung nicht gesehen habe!

Klappt natürlich problemlos!

Vielen Dank nochmals! =)

08.09.2011 - 13:06 Uhr

verwendetes Datenbanksystem: <SQLServer 2005, SQLServer2008 und R2>

Hallo,

per CreateQuery frage ich mit SysDateTime() das aktuelle Datum und Uhrzeit des SQL-Servers ab. Das funktioniert leider nur bei 2008R2 und nicht bei 2008 und 2005er SQL-Server.

Nachdem ich sehr viel probiert habe, fällt mir leider nicht ein, welche Funktion von CreateQuery mir das aktuelle Datum plus Uhrzeit zurückgibt und auch auf einem 2005er SQL-Server funktioniert.

P. S. Die gesuchte Methode sollte schon meine bestehende Verbindung des Entity Frameworks benutzen und auch funktionieren, wenn noch keine Datenbank existiert (also noch nichts gemappt ist). Daher mir bitte auch keine T-SQL-Anweisung mitteilen.

Im Netz habe ich folgenden Code gefunden:


return (DateTime)this.ExecuteMethodCall(this, mi, new object[] { }).ReturnValue;

Falls das der richtige Ansatz ist, habe ich aber das Problem, dass in dieser Zeile bei mir der Fehler auftritt: > Fehlermeldung:

...enthält keine Definition für "ExecuteMethodCall

  • muss ich dafür irgendwelche Verweise einfügen?

Habt Ihr eine Idee? 🙁

Vielen Dank!

01.09.2011 - 15:02 Uhr

Sehr interessante Gedanken!

auch wenn die Diskussion bereits länger zurückliegt, von mir auch ein paar Punkte (vielleicht liest ja Microsoft auch einmal mit):

Die >neue< "Windows 8" App-Oberfläche: 🙄

  • 100% Kompabilität zu allen 32- und 64- bit Programmen ist zwingend erforderlich!
  • unterstützt scheinbar keine mehreren Fenster, zwischen denen wie bisher gewechselt werden kann, die skaliert und sinnvoll angeordnet werden kann - Daher im Büro nicht nutzbar!
  • Touchscreen ist im Büro unsinnig - oder wie schwer sind Eure Arme nach einem 8 Std. Tag?
  • Keine schöne Integration zwischen >neuer< und konventioneller Oberfläche in Windows 8
  • Microsoft setzt zukünftig scheinbar mehr auf Modetrends als auf Bedienbarkeit?
  • >neue< Oberfläche auf für die zukünftigen Serverversionen? - Das wird lustig!

Office:

  • Ribbons in den Office-Programmen nerven mich auch und sind nicht intuitiver
  • Trotz weniger Funktionen im aktuellen Office ist die 2003er Version viel übersichtlicher
  • Keine direkte Sync mit Outlook und dem WindowsPhone - das ist im Business-Bereich katastrophal!

.NET:

  • Microsoft hat seit ca. 2000 .NET auf die Beine gestellt, was anfangs große Mängel aufwies und gegen das viele Entwickler geflucht haben. Viele Entwickler sind dadurch von Microsoft weggegangen.
  • Sollte sich das Spiel wiederholen, wird es ernst für Microsoft.
  • Microsoft sollte besser die Programminhalte verbessern, statt permanent neue Ideen zu beginnen und dann wieder zu verwerfen.
  • Welche Technik dahintersteckt ist dem User doch egal. Warum macht Microsoft dann so etwas? - Ich vermute, dass ist nur ein Kommunikationsproblem.

Ich bin sicher, dass die >neue< Oberfläche nur auf Touchgeräten im Home-Betrieb genutzt wird. Business-Lösungen werden weiter wie bisher laufen und auch weiterhin mit dem .NET entwickelt werden.

Grüße

01.09.2011 - 13:13 Uhr

Hallo CSharperUser,

vielen Dank, das Du mir geholfen hast und gleich mehrere Lösungsansätze gegeben hast! 👍

Ich habe seit gestern an anderen "Baustellen" gearbeitet, weil ich dabei nicht mehr weitergekommen bin.

Aus unerklärlichen Gründen 🙂 tritt der Fehler nun derzeit nicht mehr auf. Scheinbar wurde dadurch die Initialisierungsdauer und Abfolge evtl. geändert. Das ist für mich natürlich auch keine perfekte Lösung, weil der Fehler dann schlimmstenfalls sporadisch beim Kunden auftreten könnte.

Eventuell kannst du das Binding im Sinne der Wertänderung selbst definieren, d.h. du sagst dem Binding explizit, wann es sich aktualisieren soll.

--> Wenn dieses Problem nochmals auftritt, werde ich so vorgehen. Das ist in meinem Fall am einfachsten. Darauf bin ich gar nicht gekommen.

Vielen Dank nochmals!!! 🙂

Grüße

01.09.2011 - 11:04 Uhr

Hallo,

in einem eigenen Usercontrol, was aus mehreren Controls besteht und wo die DependencyProperty "Wert" per Databinding gebunden wird, möchte ich, dass beim Zuweisen des Datacontexts später eine bestimmter Code "Zeigeetwas()" ausgeführt wird.

-> weise nun den Datacontext nochmals explizit zu und es klappt jetzt. Bei Textboxen o.ä. ist das Vorgehen bei mir allerdings nicht notwendig.

01.09.2011 - 10:50 Uhr

Hallo Profis,

hat denn wirklich niemand eine Idee dazu? X(

Grüße

30.08.2011 - 10:28 Uhr

verwendetes Datenbanksystem: <SQL-Server 2005, 2008>

Hallo,

beiße mich gerade an einem Problem aus, welches bereits tausendmal auch hier im Forum angesprochen wurde, scheinbar auch gelöst wurde, aber niemals gepostet wurde:

Immer wieder Databinding und Relations
ConstraintException
XML in Datenbank
Seltsames verhalten

Eine WPF-Combobox ist gebunden. Der Inhalt (ObservableCollection, die die Auswahldaten enthält) wird geändert beim Laden und teilweise auch wenn im Fenster bestimmte Aktionen gemacht wird.

Im Hintergrund wird mit dem Entity Framework gearbeitet.

In der Datenbank ist das zugehörige Feld vom Typ "not null".

Da während des Ladens anfänglich teilweise noch keine Daten geladen wurden, ist das Combo scheinbar kurzfristig null und will dies scheinbar störrisch in das gebundene Feld schreiben. Da dieses null durch die Regeln nicht in die Entität geschrieben werden können, erscheint beim Start immer folgender Fehler:

Fehlermeldung:
System.Data.ConstraintException: Diese Eigenschaft kann nicht auf einen NULL-Wert festgelegt werden.
InnerException=null
Source System.Data.Entity
StackTrace:bei System.Data.Objects.DataClasses.StructuralObject.SetValidValue(String value, Boolean isNullable)
bei MyProgram.MyClass.set_MyText(String value)

Problem ist, dass dieser Fehler hier auftritt:


[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.String MyText

...
	_MyText = StructuralObject.SetValidValue(value, false);
...

Da dieser Code vom Entity Framework automatisch erzeugt wurde (und das Datenbankmodell von Zeit zu Zeit immer wieder einmal neu generiert wird) kann ich diesen Code ja nicht einfach ändern.

Vorgabe ist aber, dass in der Datenbank das Feld "not null" sein muss.

Wie kann ich die Fehlermeldung verhindern? Sie tritt nicht an einer bestimmten Stelle in meinem C# Code auf, sondern scheinbar im WPF-Form zu teils unterschiedlichen Zeiten. Ich kann den Fehler daher nicht abfangen.

this.dataSet1.EnforceConstraints = false; kann ich nicht verwenden, da ich nicht wüsste, wie dies beim Entity Framework funktionieren sollte.

Nun bin ich wirklich ratlos. 🙁

Kann mir da wirklich niemand helfen? X(

Grüße

29.08.2011 - 16:02 Uhr

Hallo Florian,

nein, bestimmt ist das nicht stümperhaft, da es exakt das war, wonach ich ja gefragt hatte - direkt im Join.

Aber der EXISTS ist einfach für mich doch auch passender.

Grüße

29.08.2011 - 13:07 Uhr

Hallo Florian,

super, vielen Dank! Ich hatte mich zwar zuerst gegen einen ...IN-Select gesträubt, da ich dazu je nach Abfrage einen vorhandenen Sql-Select anders abfragen müsste (über case und dann zwei unterschiedliche Selects), jedoch überzeugte mich Dein WHERE NOT EXISTS (einerseits aus Performancegründen, andererseits, da ich darin auch meine andere Abfrage leicht anpassen könnte) doch so stark, dass ich dies nutzen werde!

Nochmals herzlichen Dank für die wirklich schnelle und Top-Hilfe! 👍

Grüße

29.08.2011 - 12:30 Uhr

Hallo Florian,

Danke für Deine Antwort. Nein, es soll kein Produkte.Produkt zurückgeliefert werden. Ich habe diese Spalte am Anfang nur drinnen, um mir beim manipulieren am Select null-Werte o. a. anzuzeigen.

Es sollen wie gesagt nur die Kunden zurückgegeben werden, für die in der Produkt-Tabelle keine Sparte mit =10 hinterlegt ist.

Das man eine Liste erhält für die Kunden, bei denen man die Sparte=10 noch hinterlegen muss.

Nur wie?

Es sollte aber in einer einzigen SQL-Bedingung abfragbar sein und am besten komplett in der JOIN-Bedingung stehen können (und möglichst ohne SELECT IN).

Grüße

29.08.2011 - 11:51 Uhr

verwendetes Datenbanksystem: <SQL-Server 2005, 2008>

Hallo,

es sollen die Kunden ermittelt werden, zu denen nicht in einer Untertabelle Produkte einer bestimmten Sparte mit SparteId=10 zugeordnet wurden:

SELECT Produkte.Produkt, Kunden.Name
FROM Kunden
RIGHT OUTER JOIN (Produkte ON Kunden.Id = Produkte.KundenId AND
                      Produkte.SparteId = 10) [I]AND Produkte.Id=NULL[/I]
WHERE (...)

Bsp.

Kunde "Mustermann", id=1
Kunde "Meier", id=2

Produkt "Nudeln", id=99, KundenId=1, SparteId=8
Produkt "Erbsen", id=100, KundenId=1, SparteId=10
Produkt "Linsen", id=101, KundenId=2, SparteId=15

Soll nur 1x"Meier" zurückliefern, da für Meier in der Produkt-Tabelle für die Sparte=10 kein Eintrag existiert.

Die obere Bedingung klappt natürlich nicht. Es sollte aber in einer einzigen SQL-Bedingung abfragbar sein und am besten komplett in der JOIN-Bedingung stehen können (und möglichst ohne SELECT IN).

Wie ist das möglich? Ich stehe da momentan leider auf dem Schlauch, obwohl das ja gar nicht kompliziert ist. 🤔

Danke!

15.08.2011 - 12:30 Uhr

Hallo Gü,

ich war im Kurzurlaub und kann mich erst jetzt melden.

Vielen Dank für den Code gleich als IEnumerable und ExtensionMethod! Wer diesen Code nutzt, muss allerdings berücksichtigen, dass z. B. folgende Verweise auf andere Tabellen und Referenzen hier noch mit enthalten sind, da diese ja auch im ObjectContext vorkommen:

  • MyProject.Tabelle1 Tabelle1
  • System.Data.Objects.DataClasses.EntityReference`1[MyProject.Tabelle2] Tabelle2Reference

Ich frage nun die Felder daher zusätzlich nochmals einzeln ab und das funktioniert auch.

Vielen Dank! 👍

Grüße

09.08.2011 - 16:24 Uhr

Hallo,

also ich habe nun ziemlich viel versucht. GetMembers(), GetProperties() und auch per PropertyDescriptor. Ich finde keinen Unterschied, an dem ich erkennen kann, ob es sich um ein Datenbanksfeld handelt. Alle Member sind auch vom Typ MethodInfo.

Vielleicht weiß noch jemand einen Rat.

Ansonsten funktioniert diese Methode wirklich ausgezeichnet! Vielen Dank!

Grüße

09.08.2011 - 14:15 Uhr

Hallo Gü,

Super!!! 👍 PropertyInfo war das Stichwort. Einziges Problem noch, wie kann ich nur meine wirklichen Felder (z. B. "Name", "Vorname", "ID" etc. herausfiltern?

Ich bekomme noch ziemlich viele andere Properties z. B. KundeProperty, EntityState etc...

Derzeit suche ich unter property.GetType(), habe aber noch nichts passendes gefunden.

propery.MemberType ist immer "Property" und kann nicht zur Unterscheidung herangezogen werden.

Grüße

09.08.2011 - 13:36 Uhr

Hallo Gü,

ja, nur SaveChanges schreibt die Änderung bereits in die Datenbank. Ich möchte aber an dieser Stelle noch nicht so weit gehen und die Daten nur in meiner ObservableCollection lokal auf dem Rechner "speichern".

Ich würde also nach meinem Clone() nur eine allgemeine Änderungsübernahme-Methode zurück zum Ursprung der Clone-Quelle benötigen.


...
Kunde tempkunde=(Kunde)kunde.Clone();
...
if (ok)
{
  UpdateObject(tempkunde, kunde);
}

09.08.2011 - 13:28 Uhr

Hallo FZelle,

danke für die schnelle Antwort!

So viel wie ich dazu gelesen habe, kann IEditableObject per CancelEdit Änderungen rückgängig machen. (D. h. es arbeitet wie ein Rollback, was ich eigentlich aus folgenden Gründen vermeiden wollte:)

Mein Objekt befindet sich aber leider in einer oder mehreren ObservableCollections, die zu einem Zeitpunkt im Programmablauf existieren. Um nicht die Änderungen des Objekts in diesen ObservableCollections während meiner Bearbeitung durchzuführen, arbeite ich mit einem Klon.

IEditableObject (BeginEdit) würde in meinem Fall auch dieses Objekt in allen ObservableCollections beeinflussen. Das soll aber definitiv noch nicht passieren.

Ich benötige doch eher eine Methode mit folgenden Parametern:

public void UpdateObject(object Quellobjekt, object Zielobjekt)

Im Quellobjekt sollten dann alle in der DB vorhandenen Felder z. B. per foreach durchgegangen werden und wenn sich diese geändert haben, im Zielobjekt geändert werden. Dabei soll im Zielobjekt PropertyChanged ausgelöst werden.

Nur wie kann man das realisieren?

Danke

09.08.2011 - 12:33 Uhr

Hallo,

ich kopiere flach eine Entity Klasse mit Klasse.Clone(), damit der Benutzer in Ruhe an der Klasse arbeiten kann, ohne dass sich die Original-Klasse ändert und die Änderungen auf Wunsch nicht übernommen werden müssen.

Die Übernahme habe ich mir so vorgestellt:
Ich möchte eine Klasse erstellen, die NUR alle Änderungen der geclonten Klasse auf die Originalklasse überträgt. Dazu müsste diese Methode nur meine Felder (die auch in der Datenbank vorhanden sind) prüfen und ggf. updaten, nicht aber die komplette Klasse kopieren (wie die meisten DeepCopy-Methoden). Nur wenn sich etwas geändert hat, sollte PropertyChanged ausgelöst werden.

Nun bin ich über viele DeepClone Möglichkeiten gestolpert, (teils auch über einen Constructor etc.). Ich benötige aber keine tiefe Kopie der kompeltten Klasse, sondern nur einzelner Felder bei Änderungen.

Auch hier gibt es bereits einige Interessante informationen, leider aber in eine andere Richtung: Kopie ohne ICloneable [oder warum man Objekte nicht kopieren sollte; Transaktionen auf Objekten].

Muss ich dies mit einer foreach-Schleife realisieren, oder gibt es da einen einfacheren Ansatz. Bei foreach habe ich die Schwierigkeit, dass es auf alle Klassen angewendet werden sollte. Wonach muss ich im Netz suchen?

P.S. Rollback o.ä. sind für mich nicht sinnvoll.

Danke!