Recently in c# Category

DataTable Key/Value columns to Dictionary

|
There are undoubtedly more elegant ways to do this using LINQ, but to quickly and easily take the key (int) and value (string) columns from a DataTable and turn them into a Dictionary<int, string>, the following method has come in handy recently:

        public static Dictionary<int, string> GetAsDictionary(DataTable data, string keyField, string valueField)
        {
            Dictionary<int, string> dictionary = new Dictionary<int, string>();

            foreach (DataRow row in data.Rows)
            {
                dictionary.Add(Convert.ToInt32(row[keyField]), Convert.ToString(row[valueField]));
            }

            return dictionary;
        }

MySql ServerName.Log file size

|
A quick and dirty hack (written in C#) to solve the issue of MySql query log files getting huuuge:

System.ServiceProcess.ServiceController sc = new ServiceController("mysql", "servername");
sc.Stop();
Console.WriteLine("Stopping");
sc.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0, 0, 30));
Console.WriteLine("Stopped");
System.IO.File.Delete(@"\\servername\C$\Program Files\MySQL\MySQL Server 5.0\data\ServerName.log");
Console.WriteLine("Starting");
sc.Start();
sc.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 30));
Console.WriteLine("Started");
I have this compiled into a CruiseControl task that runs at 7am every day, no more massive log files and a lot easier than trying to decipher the MySql documentation. Plus, I've got some other odds and ends of maintenance that I've shoe-horned in. Not necessarily elegant, but it works!

Why "int foo = 0;" is pointless in variable declarations

|
From: What does the optimize switch do?

Part of the way down:

* We omit generating code for things like int foo = 0; because we know that the memory allocator will initialize fields to default values.
The key there is that "the memory allocator will initialize fields to default values" ... see, there's really no point in setting fields to their default values, it's just code clutter. The compiler throws it away, and even if it didn't, the memory allocator would make it entirely pointless!

Coolite - File Upload Dialog & other breaking changes

|
I think I've mentioned the custom File Upload Dialog for Coolite previously which sadly doesn't seem to work with Coolite v0.8 due to a breaking change that's not mentioned in the Version 0.8.0 -BREAKING CHANGES forum post. In summary, the ParameterCollection object no longer has a "ToJsonObject" method, but this has been replaced/renamed with "ToJson". Changing the source for the file upload dialog and re-compiling resolves this.

I also found that, as mentioned in ScriptContainer location not honoured in 0.8 against 0.7, the behaviour of the Coolite ScriptContainer has changed as it now seems to have been split-out into the ScriptContainer and StyleContainer controls. Easily solved, but no less annoying that I had to spend time doing so.

extJs: Combobox .getValue oddity - 2 (The "Solution")

|
Previously: extJs: Combobox .getValue oddity

Here's a quick-hacky solution (a better one would be to ensure your combobox's are selection-only):

Ext.override(Ext.form.ComboBox, {
    getValue: function()
    {
        return this.value;
    }
    });

Coolite documentation

| | Comments (3)
It might only have been auto-gen'd from the sourcecode, but it's still better than nothing: Coolite Toolkit Documentation. The quality of (or lack of) documentation seems to be a fairly frequent complaint on the Coolite forums, and as there's not quite always a one-to-one mapping between Coolite and extJs, looking at the (comprehensive) extJs documentation isn't always useful.

In addition, to anyone working with Coolite, I would strongly recommend downloading the sourcecode and reviewing it when you come across strange/unexpected/confusing behaviours. It's not that difficult to step-through and get a fairly good idea of what's going on!

extJs: Combobox .getValue oddity

| | Comments (2)
At least in extJs version 2.2.1 (the version baked into Coolite v0.8), the getValue function on the Ext.form.ComboBox appears to be thus:

function()
{
  if (this.valueField&&this.forceSelection)
  {
    return typeof this.value!="undefined"?this.value:"";
  }
  else
  {
    return Ext.form.ComboBox.superclass.getValue.call(this);
  }
}
Of interest is the fact that differing code-paths are taken based on the "forceSelection" property. If it's set (i.e. thou shalt choose something from this combo and not enter free-text), then the .value property is used as the return value of the call to getValue, otherwise a call is made to superclass.getValue, which returns something quite entirely different!

Instead of, as expected, returning the "key" value, it returns the displayed value. This is thanks to superclass.getValue being defined as:

function()
{
  if (!this.rendered)
  {
    return this.value;
  }
  var v=this.el.getValue();
  if (v===this.emptyText || v===undefined)
  {
    v='';
  }
  return v;
}
Whilst I've logged this as an "oddity", it is (seemingly) "by-design" as the combo-box allows for user-entered values, which is what the "forceSelection" code-branch causes. That said, I firmly believe that if the "selected value" is one that has been chosen from the contained items, then getValue should return in the same way as it does with forceSelection being false.

MySql - Running a complex script using the .net Connector

|
[The solution was discovered via this entry in the mysql.com forums]

I your MySql script contains code like

"/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;"
You'll need to add "Allow User Variables=true" to your connection string. This can be achieved by manually adding it to the string, or, if using a MySqlConnectionStringBuilder, something similar to the following:

var builder = new MySqlConnectionStringBuilder
{
     Database = database,
     Server = Server,
     Password = Password,
     UserID = Username
};
builder.Add("Allow User Variables", true);
Make sure you're using at least version 5.2.6 of the MySql Connector/Net though! The forum posting states that it works with 5.2.2, but it didn't work with the copy of 5.2.2 I hav, but did with 5.2.6.

Other useful links from the forums:
Re: How do i run a *.sql script from my c# environment?

A string of character 'x' the same length as string 'y'

|
... is quite simple in .net, as I found out!

            string title = "My line of text that I'm writing to the console underlined with equals signs";
            Console.WriteLine(title);
            Console.WriteLine(new String('=', title.Length));

PDB Files ... The Complete Works - there's more!

|
One of the really annoying things with PDB files is when you don't have them for something. Be it 3rd party component, module you just plain don't care about. John Robbins seems to be the PDB guru and has written "Keeping specific PDB files from loading in the debugger".

The guy's a genius.

PDB Files ... The Complete Works

|
Just because these two articles really can't get enough link-love! The definitive guide to PDB files, what they are, how to use them and why you (as a developer) should have a really deep understanding of just how much easier they can make your life.

John Robbins - PDB Files: What every developer must know
John Robbins - Visual Studio remote debugging and PDB files

Miscellanea 16

|
Another load of "Notes to Self", this time around changing a users password on a remote machine / domain:

And *creating* a user: pinvoke.net: NetUserAdd

Sorting the results of DirectoryInfo.GetFiles

|
Say you wanted toget a list of all the SLN (Visual Studio Solution) files in a given directory and all child directories, sorted alphabetically, you could use something similar to this:

        public static void GetSolutionList()
        {
            DirectoryInfo d = new DirectoryInfo(@"C:\Solutions\");
            FileInfo[] items = d.GetFiles("*.sln", SearchOption.AllDirectories);

            Array.Sort(items, new FileInfoComparer());
            List<string> solutions = new List<string>();

            foreach (FileInfo f in items)
            {
                solutions.Add(f.FullName);
            }
        }
        public class FileInfoComparer : IComparer<FileInfo>
        {
            public int Compare(FileInfo x, FileInfo y)
            {
                return ((new CaseInsensitiveComparer()).Compare(y.Name, x.Name));
            }
        }

The key bit of "magic" is the FileInfoComparer - whilst this is a simple one, it shows how easy it is to implement a comparer for the purposes of sorting!

Miscellanea 15

|
Yet another link dump of things that I'm probably going to find useful:
Creating a folder inside the ZIP file with System.IO.Packaging
Fire and Forget class for ASP.NET
ASP.NET 4.0 and Visual Studio 2010 Web Development Overview

And a link that's as amusing as it is interesting, "Teach me to smoke", which reminds me of being at University where the example of how to boil a kettle was used as an exercise in exactly the same way.

A number that equals twice the sum of its decimal digits

|
Riffing on "dix-huit ans aujoud'hui = 18 pounds!" from Frankarr, an australian blogger.

In the entry he mentions that "One fact about 18 which I really love is that 18, aside from 0, is the only number that equals twice the sum of its decimal digits - cool huh?". Now, being a geek I had to write a scratch program t prove that one way or the other, without further ado here it is:

            for (int i = 0; i < int.MaxValue -1; i++)
            {
                string intValue = i.ToString();
                int sumValue = 0;
                foreach (char digit in intValue.ToCharArray())
                {
                    sumValue += ((Convert.ToInt32(digit.ToString()))* 2);
                }
                if (sumValue == i)
                {
                    Console.WriteLine("Value found: {0}", i);
                }
                int modulus = i % 100000;
                if (modulus == 0)
                {
                    Console.WriteLine(string.Format("{0}", i));
                }
            }

The second Console.WriteLine is just so that when running, I can see that the program hasn't frozen/crashed. And it's true, in all the numbers between 0 and int.MaxValue -1, there are no numbers other than 0 and 18 where his fact holds true. Geeky goodnesss!