Code Optimierung – Teil 1250 (in C# geht auch Spaghetti kodierung)

Ich bin zur Zeit, unter anderem damit beauftragt ein Projekt für einen Kunden zu überarbeiten und zu optimieren.

In diesem Zusammenhang bin ich Heute Morgen auf ein Stück Quellcode gestoßen der mich sofort an die früher (so vor 20 Jahren) sehr üblichen Spaghetti Code Programme erinnert hat.

Ich zeige hier einfach mal den Code dieser Methode wie ich sie vorgefunden habe und anschließend die von mir leicht überarbeitete Methode.

Die Methode wird übrigens dazu verwendet verschiedene Button ein und auszublenden, sowie in Abhängigkeit von Datenfeldern einer Datenbank den Button mit einem Image zu verschönern und entsprechende Datums und Uhrzeiten anzuzeigen oder auszublenden.
Ich denke anhand der nachfolgenden Abbildungen kann man sich ungefähr vorstellen was die Methode macht.

Hier der doch etwas unübersichtliche Code

#region Ankunft

if (entladung.AnkunftLKW.HasValue)
{
	dtpAnkunftDate.Visible = true;
	dtpAnkunftTime.Visible = true;
}
else
{
	dtpAnkunftDate.Visible = false;
	dtpAnkunftTime.Visible = false;
}
#endregion

#region Einfahrt

if (entladung.EinfahrtLKW.HasValue)
{
	dtpEinfahrtDate.Visible = true;
	dtpEinfahrtTime.Visible = true;
}
else
{
	dtpEinfahrtDate.Visible = false;
	dtpEinfahrtTime.Visible = false;
}

#endregion

#region Entladung Start

if (entladung.EntladeStart.HasValue)
{
	dtpEntladungStartDate.Visible = true;
	dtpEntladungStartTime.Visible = true;
	btnEntladungStart.ImageIndex = 0;
	if (entladung.EntladeEnde.HasValue)
	{
		btnEntladungStart.Enabled = false;
	}
	else
	{
		btnEntladungStart.Enabled = true;
	}
}
else
{
	dtpEntladungStartDate.Visible = false;
	dtpEntladungStartTime.Visible = false;
}

#endregion

#region Entlade Ende

if (entladung.EntladeEnde.HasValue)
{
	dtpEntladungEndeDate.Visible = true;
	dtpEntladungEndeTime.Visible = true;
	btnEntladungEnde.ImageIndex = 0;

	btnEntladungEnde.Enabled = !entladung.AusfahrtLKW.HasValue;
}
 else
{
	if (entladung.EntladeStart.HasValue)
	{
		btnEntladungEnde.Enabled = true;
	}
	else
	{
		btnEntladungEnde.Enabled = false;
		btnEntladungEnde.ImageIndex = -1;
	}

	dtpEntladungEndeDate.Visible = false;
	dtpEntladungEndeTime.Visible = false;

}

#endregion

#region Ausfahrt

if (entladung.AusfahrtLKW.HasValue)
{
	dtpAusfahrtDate.Visible = true;
	dtpAusfahrtTime.Visible = true;
}
else
{
	dtpAusfahrtDate.Visible = false;
	dtpAusfahrtTime.Visible = false;
}

#endregion

Hier der Optimierte Code

dtpAnkunftDate.Visible = entladung.AnkunftLKW.HasValue;
dtpAnkunftTime.Visible = entladung.AnkunftLKW.HasValue;

dtpEinfahrtDate.Visible = entladung.EinfahrtLKW.HasValue;
dtpEinfahrtTime.Visible = entladung.EinfahrtLKW.HasValue;

dtpEntladungStartDate.Visible = entladung.EntladeStart.HasValue;
dtpEntladungStartTime.Visible = entladung.EntladeStart.HasValue;

dtpEntladungEndeDate.Visible = entladung.EntladeEnde.HasValue;
dtpEntladungEndeTime.Visible = entladung.EntladeEnde.HasValue;

dtpAusfahrtDate.Visible = entladung.AusfahrtLKW.HasValue;
dtpAusfahrtTime.Visible = entladung.AusfahrtLKW.HasValue;

btnEntladungStart.ImageIndex = entladung.EntladeStart.HasValue ? 0 : -1;

btnEntladungStart.Enabled = ((!entladung.EntladeStart.HasValue) |
						((entladung.EntladeStart.HasValue && !entladung.EntladeEnde.HasValue)));

btnEntladungEnde.ImageIndex = entladung.EntladeEnde.HasValue ? 0 : -1;

btnEntladungEnde.Enabled = (entladung.EntladeStart.HasValue && !entladung.AusfahrtLKW.HasValue);

Man beachte die Zeilenzahlen. Die obere Variante hat genau die 4 fache Anzahl Code.
Obwohl, schön aussehen tun die vielen If’s und Else schon 🙂

Und da der untere Code viel kürzer und einfacher ist, braucht man auch nichts mehr mit Region umklammern.

Enum als Datasource für DataGridViewComboBoxColumn im DataGridView verwenden

Vor längerer Zeit habe ich in diesem Artikel berichtet wie man enum Werte über die DataSource Eigenschaft an eine Combobox binden kann.

Hier eine Darstellung einer solchen Bindung in einer normalen Windows Form:

Will man nun aber enum Werte in einem DataGridview an eine, als Combobox definierte, Spalte (DataGridViewComboBoxColumn) binden, geht das nicht ganz so einfach, und eben nicht so wie es in meinem oben erwähnten Artikel beschrieben ist.

Das Ergebnis soll so aussehen:

Wer schon einmal eine solche Tabelle programmiert hat, weiß, dass man nachdem man die DataSource Eigenschaft der DataGridViewComboBoxColumn zugewiesen hat, noch den ValueMember und den DisplayMember angeben muss (Siehe nachfolgende Abbildung).

Da wir die DataSource Eigenschaft bei der enum Variante über den Source Code zuweisen (es geht auch anders, dazu evtl. zu einem späteren Zeitpunkt mal mehr), müssen wir natürlich auch die beiden Eigenschaften  DisplayMember und ValueMember aus dem Quellcode heraus zuweisen.

Nur wie heißen die denn ?

Und genau hier liegt das Problem, bzw. die hier beschriebene Lösung.

Diese Eigenschaften gibt es bei der ursprünglich von mir beschriebenen Lösung nicht.

Und daher müssen wir uns solche Eigenschaften bilden. Hierzu verwenden ich eine Helper Klasse die das notwendige implementiert. (Siehe nachfolgenden Source Code)

Hier nun der Code der Klassen

[Serializable]
public class EnumHelper
{
	public int Key { get; set; }
	public string Value { get; set; }

	public static IEnumerable<ValueListItem> CreateDataSourceFromEnum(Type t)
	{
		var list = new List<ValueListItem>();

		Array aEnum = Enum.GetValues(t);
		foreach (var array in aEnum)
		{
			var vi = new ValueListItem
						 {
							 Key = (int) array,
							 Value = array.ToString()
						 };

			list.Add(vi);
		}
		return list;
	}

	public static IEnumerable<EnumHelper> DataSourceFromEnum(Type t)
	{
		var list = new List<EnumHelper>();

		Array aEnum = Enum.GetValues(t);
		foreach (var array in aEnum)
		{
			var vi = new EnumHelper
						 {
							 Key = (int) array,
							 Value = array.ToString()
						 };

			list.Add(vi);
		}
		return list;
	}

}

[Serializable]
public class ValueListItem
{
	public int Key { get; set; }
	public string Value { get; set; }
}

Und so kann man die Helper Klasse verwenden um die DataSource Eigenschaft sowie die ValueMember und DisplayMember Eigenschaften zuzuweisen.

private void InitDgv()
{
	bereichDataGridViewTextBoxColumn.DataSource = EnumHelper.DataSourceFromEnum(typeof(EntladungsTyp));
	bereichDataGridViewTextBoxColumn.DisplayMember = "Value";
	bereichDataGridViewTextBoxColumn.ValueMember = "Key";
}

Wichtiger Hinweis

Ich verwende diese Klasse bereits seit mehreren Jahren und weiß nicht mehr genau ob ich von irgend jemand etwas übernommen und überarbeitet habe, oder ob ich das im stillen Kämmerchen ausgebrütet habe.
Eine kurze Recherche im Internet hat keine direkten Ergebnisse / Quellen hervorgebracht. Es gibt zwar einige Beiträge die sich auch mit enum Helper Klassen beschäftigen, aber die, welche ich gerade gesehen habe, beschäftigen sich nicht genau mit dem von mir hier beschriebenen Thema, so dass ich zur Zeit keine Angaben über eventuelle Quellen, die mich inspiriert haben könnten, machen kann.

Aber wenn jemand erkennt dass ich Code von wem auch immer verwendet habe, hinterlasst dass bitte in einem Kommentar, so dass sich eventuell fehlende Quellnachweise schließen.

C# -Die Auflistung wurde geändert – Der Enumerationsvorgang kann möglicherweise nicht ausgeführt werden

Eine Meldung ähnlich wie die Überschrift kann man ganz leicht erhalten, wenn man mit Auflistungen in einer Anwendung arbeitet, welche mehrere Threads verwendet und ein Thread lesend und ein anderer schreiben auf die Auflistung zugreift.

Nun ist es so, dass es zu diesem Thema eine ganze Reihe, von mehr oder weniger, guten Ansätzen im Internet zu finden ist (Natürlich überwiegend gute 🙂 ). Wobei eine der entscheidenden Aussagen ist, dass man diese Fehlermeldungen, dann erhält wenn man mit einer Enumeration (foreach Schleife) über die Auflistung geht und dabei neue Elemente der Auflistung hinzufügen oder Elemente löschen möchte.

Also zum Beispiel wie in der folgenden Klasse:

public class AppointmentList : List<Appointment>
{
	public void DeleteAppointmentsForDate(DateTime dt)
	{
		foreach (Appointment appointment in this)
		{
			if (appointment.StartDate.Date == dt.Date)
			{
				Remove(appointment);
			}
		}
	}
}

Eigentlich soll, die Methode der Klasse alle Appointments eines bestimmten Datums aus der Auflistung löschen.
Das mach sie auch, und zwar dann, wenn alles in einem Thread abläuft.

Aber nur dann.

Nun wird bei den meisten Lösungen im Internet vorgeschlagen anstelle der Iteration mit foreach einfach eine for Schleife zu verwenden.

Das würde dann so aussehen
(Ich möchte aber gleich hier sagen, dass diese Lösung für das Löschen auch nicht eingesetzt werden kann, da diese egal ob mit oder ohne mehreren Threads nicht richtig arbeitet).

public class AppointmentList : List<Appointment>
{
		for (int i = 0; i < this.Count; i++)
		{
			if (this[i].StartDate.Date == dt.Date)
			{
				this.RemoveAt(i);
			}
		}
	}
}

Und warum geht das nicht ?

Nehmen wir der Einfachheit halber mal an die Auflistung würde 4 Einträge enthalten und alle 4 würden das gleiche Startdatum haben, was bedeuten würde, dass alle 4 Listen Elemente gelöscht werden müssten.

Runde 1:
i == 0 und this.count== 3
Element an Index 0 wird gelöscht
Element mit Index 1 wird nun an Index Position 0 geführt
Element mit Index 2 wird nun an Index Position 1 geführt
Element mit Index 3 wird nun an Index Position 2 geführt
this.count ist nun nur noch 2

Runde 2:
i == 1 und this.count == 2
….

Eigentlich brauche ich gar nicht mehr weiter erläutern, jetzt ist klar, dass das löschen mit der for schleife mit erhöhendem Index (i++) nicht funktionieren kann, wenigstens nicht wenn es um das Löschen von List Elementen geht.

Aber natürlich gibt es auch dafür eine einfache Lösung, und diese sieht so aus:

public class AppointmentList : List<Appointment>
{
	public void DeleteAppointmentsForDate(DateTime dt)
	{
            for (int i = this.Count - 1; i >= 0; i--)
            {
                if (this[i].StartDate.Date == dt.Date)
                {
                    this.RemoveAt(i);
                }
            }
		}
	}
}

Genau, wir verwenden einfach eine for schleife mit einem herabzählendem Index (i–).
Dies funktioniert auch mit mehreren Threads.

C# – Dauer in Minuten aus Start und Ende Zeit ermitteln

Und wieder mal geht es um Zeitberechnung in C#.

Aufgabenstellung:
Wir haben 2 Datumswerte mit Zeitangabe. Nenne wir den ersten den Starttermin und den zweiten den Endetermin.
Aus diesen beiden Werten wollen wir nun die Dauer des Termins in Minuten ermitteln.

Und hier die Lösung:

DateTime _dtStart = DateTime.Now;
DateTime _dtEnde = _dtStart.AddHours(1); // Zum Test 1 Stunde addieren, das macht dann  60 Minuten Dauer

int dauer = (int) (_dtEnde - _dtStart).TotalMinutes;

Übrigens geht das natürlich auch wenn man anstelle einer DateTime Variable einen bzw. zwei DateTimePicker Werte verwenden möchte mann muss dann lediglich die Eigenschaft Value des DateTimePicker verwenden, also so:

            DateTimePicker dtpStart = new DateTimePicker();
            DateTimePicker dtpEnde = new DateTimePicker();
            dtpStart.Value = DateTime.Now;
            dtpEnde.Value = dtStart.Value.AddHours(1);

            int dauer = (int)(dtpEnde.Value-dtpStart.Value).TotalMinutes;

c# – Splitt Container Collapse Panel Advanced Example – WinForm

In einem aktuellen Projekt hat sich der Kunde gewünscht, ein „platzsparendes“ Winform, zur Anzeige von Kalenderinformationen, zu erhalten. Und da der Wunsch des Kunden gleich einem Befehl ist…. 🙂 Voila !

Hier (m)ein Lösungsansatz.

Und da ich denke, dass auch im Zeitalter von WPF, noch immer WinForm Anwendungen erstellt werden, veröffentliche ich diesen Lösungsansatz (der übrigens schon in einigen Projekten eingesetzt wird und nicht ganz neu ist) hier in diesem Beitrag und hoffe dass dies dem einen oder anderen auch Heute noch dabei behilflich sein kann, ein ähnliches Problem so einfacher lösen zu können.
Wer das Beispiel 1 : 1 in einem eigenen Projekt verwenden möchte:

Bitte schön !!!

Hier kurz noch einmal die Aufgabenstellung:
Die Form soll auf der linken Seite ein Calendar Month Control enthalten und auf der rechten Seite ein TabControl enthalten, welches dann ein komplexes Calendar Control (ähnlich wie Outlook Kalender) enthält.
Und genau da kommt wohl auch der Wunsch her, dass man das Calendar Month Control ausblenden und einblenden kann.

Eigentlich ….
gar nicht so aufwendig, aber ….
Wenn man das ganze umsetzen will, stößt man doch recht schnell an die „einfachen“ Grenzen der verfügbaren Controls.

Zur Demonstration, dass es doch nicht so aufwendig ist, habe ich dieses kleine Beispiel erstellt, welches man auch als VS2010 Projekt am Ende des Beitrags herunterladen kann.

Außer, dass man, die benötigten Controls in der richtigen Reihenfolge auf das Form ziehen muss (Siehe im Source Code) benötigt man nur ein paar Zeilen, den ich nachfolgend Kurz zeigen möchte.

namespace WinFormSplittContainerAdvancedExample
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            splitContainerRight.Panel1Collapsed = true;
        }

        private void btnHideLeftPanel_Click(object sender, EventArgs e)
        {
            splitContainerMain.Panel1Collapsed = true;
            panelShow.Visible = true;
            splitContainerRight.Panel1Collapsed = false;
        }

        private void btnShowLeftPanel_Click(object sender, EventArgs e)
        {
            splitContainerMain.Panel1Collapsed = false;
            panelShow.Visible = false;
            splitContainerRight.Panel1Collapsed = true;
        }
    }
}

Und so sieht das ganze im laufenden Betrieb aus:

Hier der Screenshot mit angezeigtem linken Kalender Panel

Und hier der Screenshot mit ausgeblendetem linken Kalender Panel

Und hier der Download: WinFormSplittContainerAdvancedExample (Einfach ZIP File entpacken und mit Visual Studio 2010 öffenen.

Viel Spaß!!

SQL Transaktionsprotokoll verkleinern (sichern) – SQL 2005 – SQL 2008

Bereits vor 6 Jahren (wie die Zeit vergeht) hatte ich in einem Artikel „SQL 2000 Transaktionsprotokoll verkleinern“ beschrieben wie man ein zu groß gewordenes Transaktionsprotokoll verkleinern kann.

Da die neuere Version SQL 2008 nicht mehr über die Option WITH TRUNCATE_ONLY verfügt, funktioniert die beschrieben Methode nicht mehr.

Nachfolgend möchte ich daher eine alternative Method vorstellen, welche den gleichen  gewünschten Effekt hat.

Das verkleinern des Transaktionsprotokolls.

Damit die Verkleinerung des Transaktionprotokolls nicht zu problemen bei einer eventuellen Rücksicherung führt, würde ich vor dem verkleinern unbedingt eine Sicherung der Datenbank und des Transaktionsprotokolls durchführen. Denn nur die Sicherung des Transaktionsprotokolls ermöglicht auch das spätere verkleinern.

Hier also nun der Transakt SQL Code zur Speicherung der DB und des Logs mit anschließendem Verkleiner der Transaktionsprotokoll Datei.

USE pubs
BACKUP DATABASE pubs TO DISK='C:\SqlDataBackup\pubs.bak' WITH INIT
BACKUP LOG pubs_log TO DISK='C:\SqlDataBackup\pubs_log.bak' WITH INIT
DBCC SHRINKFILE(pubs_Log, 10)
GO

Am besten kann man das in einer Batch Datei (Kommando Stapeldatei) einbauen und z. B. regelmäßig als Tast auf dem Rechner laufen lassen.
Wer das regelmäßig ausführen möchte kann das auch in eine Batch Datei packen und von der Kommandozeile ausführen. Was übrigens auch dann als Task ausgeführt werden kann.

@ECHO OFF
set SQL_UTIL_HOME="%ProgramFiles%\Microsoft SQL Server\100\Tools\Binn\osql"
rem Tragen Sie in der nachfolgenden Zeile den Namen des SQL Server ein z.B. (localhost)
set SQL_SERVERNAME=localhost
rem Tragen Sie in der nachfolgenden Zeile den Namen der zu sichernden Datenbank ein
set SQL_DBNAME=pubs
set SQL_LOGNAME=pubs_log
rem Tragen sie den Namen inkl. Pfad der Backup Datei ein
set SQL_BACKUP_FILE='C:\SqlBackup\pubs.BAK'
set SQL_LOG_FILE='C:\SqlBackup\pubs_log.BAK'
@ECHO ON
@ECHO Datenbank sichern
%SQL_UTIL_HOME% -S%SQL_SERVERNAME% -E -n -Q "BACKUP DATABASE %SQL_DBNAME% TO DISK = %SQL_BACKUP_FILE% WITH INIT;"
@ECHO Protokolldatei sichern
%SQL_UTIL_HOME% -S%SQL_SERVERNAME% -E -n -Q "BACKUP LOG %SQL_DBNAME% TO DISK = %SQL_LOG_FILE% WITH INIT;"
@ECHO Protokolldatei verkleinern
%SQL_UTIL_HOME% -S%SQL_SERVERNAME% -E -n -d%SQL_DBNAME%  -Q "DBCC SHRINKFILE(%SQL_LOGNAME%, 10)"

Wenn man nun noch ein Backup Programm wie Cobian Backup verwendet um die erzeugten Datenbank Backup Dateien auf einen FTP Server zu sichern, hat man eine kostenlose Lösung zur Sicherung der SQL Datenbank.

Ich denke, ich werde bald man in einem neuen Beitrag beschreiben, wie man Dedizierte WEB Server, die man bei einem Hoster stehen hat, mit Hilfe von Batch Dateien und Cobian Backup WEB Seiten inkl. Datenbanken ganz einfach und kostenlos sichern kann.

DotNetNuke Download Zähler – Wunsch oder Wahrheit ?

Ein Blick in den Seitenquellcode der Seite www.dotnetnuke.com zeigt den nachfolgenden Code:

<script type="text/javascript">
        var interval = .1;
        var counter, count = 0, updatedate;

        $(document).ready(function () {
                $.ajax({
                        type: "GET",
                        url: "/DesktopModules/Ticker/TickerXml.aspx",
                        dataType: "xml",
                        success: function (xml) {
                                $(xml).find("Ticker").each(function () {
                                        var $ticker = $(this);
                                        counter = $ticker.find('counter').text();
                                        updatedate = $ticker.find('updateddate').text();
                                });
                        }
                });

                if(typeof(counter) == "undefined") {
                        counter = 5568487;
                        updatedate = '10/20/2010 12:00:00 AM';
                }
                /*counter = 5408328;
                updatedate = '9/23/2010 1:38:40 PM';*/

                setTimeout(function () { getcounter(); }, 250);
                setInterval("getcounter();", interval * 60 * 1000);
        });

        function addCommas(number)
        {
                number += '';
                x = number.split('.');
                x1 = x[0];
                x2 = x.length > 1 ? '.' + x[1] : '';
                var rgx = /(\d+)(\d{3})/;
                while (rgx.test(x1))
                {
                        x1 = x1.replace(rgx, '$1' + ',' + '$2');
                }
                return x1 + x2;
        }

        function getcounter()
        {
                var currenttime = new Date();

                updatedate = new Date(Date.parse(updatedate));
                var seconds = calculate(updatedate, currenttime);
                var addedupdates = Math.floor(seconds / (60*interval));

                if (count == 0)
                {
                        count = counter;
                        count = parseInt(count) + parseInt(addedupdates);
                }
                counter = addCommas(count);

                var counterarray = counter.split(",");
                var  html = '';
                for(var  i=0; i<counterarray.length; i++)
                {
                        html += '<span>'+counterarray[i]+'</span>';
                }
                $(".downloadCounter").html('Over <strong>'+html+'</strong> Downloads');

                count++;
        }

        function calculate(update, current) {
                current = new Date(current);
                update = new Date(update);

                var sec = current.getTime() - update.getTime();
                if (isNaN(sec)) {
                        //alert("input data is incorrect!");
                        $(".downloadCounter").html('Over <strong>5</strong> <strong>500</strong> <strong>000</strong> Downloads');
                }

                var second = 1000, minute = 60 * second, hour = 60 * minute, day = 24 * hour;

                var days = Math.floor(sec / day);
                sec -= days * day;
                var hours = Math.floor(sec / hour);
                sec -= hours * hour;
                var minutes = Math.floor(sec / minute);
                sec -= minutes * minute;
                var seconds = Math.floor(sec / second);

                var totalsecond = seconds + (minutes * 60) + (60 * 60 * hours) + (60 * 60 * hours * days);
                return totalsecond;
        }
</script>

Hat DotNetNuke das wirklich nötig?

Wäre nicht eine andere (an der Wahrheit angelehnte) Lösung aufrichtiger !
Ich bin übrigens über diesen Twitter Beitrag auf diesen Umstand gestolpert, und konnte es eigentlich gar nicht glauben, bis…
… bis ich selbst kurz im Seitenquelltext nachgeschaut habe.

Damit auch Nicht Programmierer wissen was da steht, hier die Aufklärung:

Durch das Script wird ein Zähler erstellt, welcher die Anzahl Downloads alle 6 Sekunden um 1 erhöht. Egal ob tatsächlich Downloads stattgefunden haben, oder nicht.

Unbelievable

c# – tabControl – tabPage – Fehlende Visible Eigenschaft

Wer in WinForms Anwendungen das tabControl einsetzt wird über kurz oder lang darüber stolpern, dass die tabPage Controls keine Visible Eigenschaft besitzen.

Das bedeute es ist weder in der Entwicklungsumgebung noch zur Laufzeit Möglich einfach durch setzen der Visible Eigenschaft einzelne tabPage Seiten zwischen sichtbar und unsichtbar umzuschalten.

Hier daher ein kleines Code Snippet mit dem man die tabPage aus dem Programmcode heraus aus der tabPage Auflistung des tabControls entfernen oder hinzufügen kann.

// Hier der Code für Visible=False
tabControlOptionen.TabPages.Remove(tabUser);

// Hier der Code für Visible=True
tabControlOptionen.TabPages.Add(tabUser);

TabPageVisibleHideDemo

MySQL WordPress Datenbank Engine von InnoDB auf MyIsam ändern

Über das Thema welcher Tabellentyp (InnoDB oder MyIsam) für MySQL die bessere, schnellere oder robustere ist gibt es Unmengen an Diskussionen im Internet und ich möchte an dieser Stelle nicht damit weitermachen.
Vor allem nicht, da ich mich mehr im Umfeld von MS SQL Server bewege und MySQL nur hier und da verwende.

Im Zuge meiner Blogumstellung von dasBlog auf WordPress bin ich aber auf das Problem gestoßen, dass die von mir erstellte MySQL Datenbank für WordPress als Standard den Tabellentyp InnoDB verwendet hat, was für mich zuerst auch kein Problem dargestellt hat, sich aber im Laufe der weiteren Einrichtung von WordPress für mich doch als falsch herausgestellt hat. Eines der Plugins, welches Volltextsuche verwendet, setzt voraus dass die table_wp_posts als Tabellenformat das MyIsam Format verwendet.

Da ich in einer Datenbank nicht verschiedene Tabellenformate verwenden wollte, musste ich das Tabellenformat aller Tabellen ändern. Das hätte ich entweder für jede Tabelle manuell über phpMyAdmin machen können (was aber selbst bei nur 15 Tabellen) doch einige Zeit in Anspruch nimmt und vor allem wollte ich für spätere Tests eine schnelle Möglichkeit haben, den Tabellentyp sehr schnell von einem Format zu einem anderen zu ändern.

Das Resultat ist dieses nun folgende SQL Script was einfach über den phpMyAdmin ausgeführt werden kann.

alter table wp_blc_filters ENGINE=myisam;
alter table wp_blc_instances ENGINE=myisam;
alter table wp_blc_links ENGINE=myisam;
alter table wp_blc_synch ENGINE=myisam;
alter table wp_commentmeta ENGINE=myisam;
alter table wp_comments ENGINE=myisam;
alter table wp_links ENGINE=myisam;
alter table wp_options ENGINE=myisam;
alter table wp_postmeta ENGINE=myisam;
alter table wp_posts ENGINE=myisam;
alter table wp_terms ENGINE=myisam;
alter table wp_term_relationships ENGINE=myisam;
alter table wp_term_taxonomy ENGINE=myisam;
alter table wp_usermeta ENGINE=myisam;
alter table wp_users ENGINE=myisam;

Und wenn man die Engine von MyIsam nach InnoDB ändern möchte geht das natürlich auch.

alter table wp_blc_filters ENGINE=innodb;
alter table wp_blc_instances ENGINE=innodb;
alter table wp_blc_links ENGINE=innodb;
alter table wp_blc_synch ENGINE=innodb;
alter table wp_commentmeta ENGINE=innodb;
alter table wp_comments ENGINE=innodb;
alter table wp_links ENGINE=innodb;
alter table wp_options ENGINE=innodb;
alter table wp_postmeta ENGINE=innodb;
alter table wp_posts ENGINE=innodb;
alter table wp_terms ENGINE=innodb;
alter table wp_term_relationships ENGINE=innodb;
alter table wp_term_taxonomy ENGINE=innodb;
alter table wp_usermeta ENGINE=innodb;
alter table wp_users ENGINE=innodb;

c# – Windows 7 – Lokale IPV4 Adresse ermitteln

Einige meiner Tools (darunter vor allem eine Monitorprogramm zur Überwachung von Windows Diensten auf Basis eines UDP TraceListener) funktionieren unter Windows 7 nicht mehr korrekt.

Besser gesagt, beim versucht die lokale IP Adresse zu ermitteln tritt folgender Fehler auf:

{System.Net.Sockets.SocketException: Es wurde eine Adresse verwendet, die mit dem angeforderten Protokoll nicht kompatibel ist
   bei System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
   bei System.Net.Sockets.Socket.Bind(EndPoint localEP)

 

Der nachfolgende Code Ausschnitt hat unter Windows XP noch einwandfrei funktioniert:

HostIP = Dns.GetHostAddresses(Dns.GetHostName())[0];
endPoint = new IPEndPoint(HostIP, _Port);
UDPSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
UDPSocket.Bind(endPoint);

Unter Windows 7 wird aber dabei eine IPV6 Adresse zurückgegeben, mit welcher das Binden des UPD Socket nicht funktioniert.

Nachfolgend nun eine Methode die sowohl unter Windows XP (und den anderen älteren Betriebssystemen) als auch den aktuellen Betriebssystemen wie Windows 7 und W2K8 Server  funktioniert.

foreach (IPAddress address in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
{
    if (address.AddressFamily != AddressFamily.InterNetworkV6)
    {
        HostIP = address;
        break;
    }
}
endPoint = new IPEndPoint(HostIP, _Port);
UDPSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
UDPSocket.Bind(endPoint);