Sunday, February 02, 2014

CAR IT: Mazda CX-5 Bluetooth Does Not Download Text Message on iPhone

Symptom:

On your Mazda CX-5, you have successfully paired the Bluetooth and it works mostly but when it comes to text message, it prompts you to Download but it does not show any message with your Apple iPhone.

Fix:

Two answers.

First answer is, there is no fix for this so just give up and deal with it.

Second Answer:

The only phone that is 100% compatible with your CX-5's sound system appears to be Motorola Moto-X, so if you absolutely have to have everything working that's one of the options that is likely to work. I recently changed to Moto X and have confirmed that it works completely.

Apple is not the only phone that does not work with your Mazda, Nokia Windows phone would not work neither are many other Android phones or even plain pocket phones.  According to recent inputs, Samsung phone are working well too.

Mazda does have a compatibility list at this web site: http://www.mazdausa.com/MusaWeb/displayPage.action?pageParameter=bluetooth

Note, in general in 2014 when I writing this, there are still quite a bit of incompatibilities among all car systems paired with different phones. So I would not advise going all the way to buying a different car that's compatible with your iPhone.

At any rate, wait for a few more years (wait until 2016 or later model year cars) when all of this is settled, which is likely to occur.  If you are or will be in a market for a new car, you may have to research if your phone brand or even carrier carefully. Your brand new $45,000 car can easily ruin your phone experience and little did you know that your $5,000 investment in iTunes purchases go down the drain.




CAR IT: Mazda CX-5 (or others): Inflate Tire Pressure Warning But Tires Are All Inflated

OK, this is not a computer topic. Well actually it is. It is your car computer problem.

Symptom:

Your Mazda CX-5 warning message come up saying "Inflate Tire Pressure." You checked the pressure and pressed the Pressure Reset button but nothing happens.

Fix:

There are two ways this info comes on. One is actual low pressure condition. Another is that there is a Maintenance Timer in your INFO mode which you can reset and adjust yourself!

If this happens, park your car in a safe place, and press the INFO button, then you should be able to scroll the menus through Maint mode.

In there you will find the Tire Pressure check maintenance mode. This is a count-down timer and will tell you how many days or months between checks.

Of course, the purpose of this is for it to remind you to check the tire pressure from time to time, so now is a good time to check it and set it up to remind you in a few months, but there is no need to panic.

Side Note: This comes on immediately after you start an engine then it is very likely due to the reminder since the "actual" tire pressure warning won't kick-in until all the wheels are in motion at speed. Your Mazda CX-5 (an many other Mazdas too) uses the wheel rotational speed differential sensing technology and not the actual air pressure monitor stems in the tires. Since the rotational detection is significantly inexpensive to implement as most cars have ABS wheel speed sensors this is becoming much common. In addition this will never run out of the sensor batteries which is the case with the stem embedded pressure sensors. My other car had the stem sensors and after the 8th year, the batteries started to "go" one by one, about $250 replacement cost each. $1000 total.

Saturday, January 25, 2014

Very Basic Configuration Tips with Windows Git SSH

Like most of us you probably started using Git (GitHub most likely) on Windows and found this notion of SSH a bit challenging especially on Windows where Unix like OS manners are imposed on Windows OS and if you do not have exposure to Unix it will be really confusing.

As a programmer, though you think you can go fancy, perhaps even feeling more secure and you do not follow any of the instructions in the book and create directories and name key files the way you want them.

For this, that's where the problem starts to happen. Many Unix based systems for which Git is based on rely on the configurations in default ways. Experts know how to override them in a fairly complex ways like environmental variables or config file edits if you know which ones to manipulate.

You will learn about those as you go... But if you are starting out, don't go fancy, just use the default values as described in the documents and also store the files in the default places where the system expects them to be.

For example, when you run ssh-keygen it outputs id_rsa for the public key and id_rsa.ppk for the private key. Please do note that id_rsa is a file name not a directory. Or maybe you used another SSH key generator where id. RSA could come first with id_rsa.pub in which case you do need to remove .pub or the rest of the system by default won't recognize it. By the way, the easiest and fastest way is to just use ssh-keygen from the bash command line.

There files should be stored in where the Bash wants them to be. That's ~/.ssh  Do not put them anywhere else. Of course you may be wondering where is ~/.ssh is.

When transacting with files with bash, always use bash and do not use Windows CMD shell. Since Windows command shell does not like file or directory names that starts with a period.

Having said that, for example my user name is stokemaster then the ~ directory is at C:\Users\stokemaster so the .ssh would go to C:\Users\stokemaster\.ssh

Lastly, for the passwords don't go too fancy with it at first either! I had a % sign in my password and ssk-keygen did not like it at all. Don't waste too much time, just try a password consisting of just numbers, upper and lower case letters to make it easy.

Again, I have to stress that don't go too fancy.

Next, you would not want to type in user name and password every time you use Git. There is a script to help you do this as described on this page. https://help.github.com/articles/working-with-ssh-key-passphrases

You might be wondering how to make .profile file or .bashrc file. Here is how;

  • Start with the MsysGit bash window (not DOS command window), 
  • type in: cd ~ [ENTER] to go to the home directory. (Enter is the single Enter key I am talking about.)
  • type in: touch .profile [ENTER] (or .bashrc) which will create an empty file.

Now you can use notepad or Notepad++ (recommended) to edit this file, just copy and paste the text in the box (no modification needed) https://help.github.com/articles/working-with-ssh-key-passphrases#auto-launching-ssh-agent-on-msysgit



Friday, January 17, 2014

Windows PowerShell Script to Restart Memory Leaking Services

Background:

You have a service or two that has a modest memory leak and you would want to restart right when it has consumed a certain amount of memory.

This approach has an advantage over scheduled restarts because it will restart the service right when it is needed, or otherwise it leaves "it" alone.

This requires the use of Microsoft PowerShell which is available for XP (as download) and built-in on Windows Vista/7 and Server 2003 or later.

First time you try to run it, it is very likely that it won't run the script locally because out of the box, the script file is disabled. You will need to manually type in after manually opening PowerShell

Set-ExecutionPolicy RemoteSigned

From that point on it should permit running.

#
# This script detects the memory usage threshold and then restarts a service named in this script. You can
# run this script periodically in Scheduled Task to restart memory leaking service.
#
# Remember to do 
# Set-ExecutionPolicy RemoteSigned 
# so that this script can run
# To run this script from a BAT, 
# powershell -File RestartService.ps1
#
# First comment out the following two lines so that you can get the basic idea of the content of this stuff by
# looking at the proc.txt output file in your editor to hunt for the process name etc.
# Then it's easier to figure out the filtering for the name and the threshold.
#
#$Processes = Get-WmiObject -ComputerName "localhost" -Class Win32_PerfFormattedData_PerfProc_Process
#echo $Processes > C:\temp\proc.txt
#
# First do the Task Manager then find the EXE that is hosting the process or its subprocess then take the .exe out of that name
# If the task manager is showing *32, do not include that either.
#
$ServiceExe="MyServer"
#
# This is the name of the service to restart, this is the 'short' service name you can find in the Service's property
#
$Service="MyServerService"
#
# This is the working set threshold. For example, 3,500,000,000 would be 3.5 GB
#
#$Threshold = 3500000000
$Threshold = 500000000
#
# Real Meat of this program
#
$Process = Get-WmiObject -ComputerName "localhost" -Class Win32_PerfFormattedData_PerfProc_Process -Filter "Name='$ServiceExe'"
$wsm = $Process.WorkingSet /1024/1024/1024;
$thgb = $Threshold/1024/1024/1024
#
# Format the numbers so they are easier to read in GB units and round up to a
# decimal places.
#
$Fwsm = $("{0:0.000}" -f $wsm);
$Fthgb =$("{0:0.000}" -f $thg
b










);
e











cho $("Worksing Set is "+ $Fwsm + " gb and threshold is " + $Fthgb  + " gb");
if($Process.workingset -gt $Threshold)
{
    Restart-Service $Service; 
    echo "Restarted
"







;
}
e








lse
{
    $delta = $("{0:0.000}" -f ($thgb - $wsm));
    echo $("Still " + $delta + " gb left. Did not restart"
);

}
sl

eep 10

Tuesday, January 07, 2014

Script to Locate A Column Name in the Entire Database

Happy 2014.

Hope you will have a productive software career with some advancements too.

This is my first post of 2014. As always I have been doing, I will continue to write "The Answers to Questions Experts Don't Know How To Answer." And also these are notes to myself as I tend to forget I have done in the past unless I document them somewhere.

Issue:

I had to figure out someone else's database work as I cannot ask this "someone" a question. I am sure you may be brought into a gig that would require figuring out other people's work without asking them the questions (often you cannot.)

In this case I needed to figure out in every table and view of the SQL Server database that contained the word "Price." Then reconstruct their relationship.

Of all the answers I found the following query worked the best for me so give this a try.

SELECT t.name AS table_name, SCHEMA_NAME(schema_id) AS schema_name,
 c.name AS column_name
 FROM sys.tables AS t
INNER JOIN sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
WHERE c.name LIKE '%Price%'
ORDER BY schema_name, table_name; 

Thursday, November 28, 2013

Fix: Windows 7 and 2008: Failed extract of third-party root list from auto update cab

Symptom:

You see the following log appear in your application log, sometimes it has CAPI2 or other stuff in there.

Failed extract of third-party root list from auto update cab at: (http://www.download.windowsupdate.com/msdownload/update/v3/static/trustedr/en/authrootstl.cab) with error: A required certificate is not within its validity period when verifying against the current system clock or the timestamp in the signed file.

Fix:

Please head straight to Microsoft KB

http://support.microsoft.com/kb/2328240

It has a "Fix It" installer to assist the fix of this issue.


Sunday, October 27, 2013

Fix for ffmpeg Resulting Movie is Flipped Vertically or Horizontally

Symptom:

I had to assemble a movie clip using ffmpeg from individual JPEG frames. In my situation I wanted to make both .ogg and .mp4 medical cine clips that can be shown directly on HTML5 web browsers.

The movie makes fine but the only issue is that the movie images are all vertically flipped.

I still do not know why the images are encoded flipped since when I view individual image using Windows Preview or other JPEG viewers, I do not get the orientation issue. It is likely though these have missing Exif header which does have orientation information that's usually supplied from cameras.

At any rate, this can actually be corrected easily.

Fix:

ffmpeg contains filters and you can do a very complex filter operations. One of the operations is flipping.

By supplying

-vf "hflip"

I can horizontally flip all frames in the movie.

-vf "vflip" does the vertical flip

and

-vf "hflip, vflip" can do both.


Thursday, August 22, 2013

LINQDataSource Fix: No applicable method 'StartsWith' exists in type 'String' OR No applicable method 'Contains' exists

Symptom:
  • You have created a LinqDataSoruce control on the Visual Studio ASP.NET web page.
  • You have set up fields to be supplied from TextBox control (may be others.) 
  • You have customized the query to use StartsWith or Contains in the Query and the following type of puzzling error appears.
No applicable method 'StartsWith' exists in type 'String'  or
No applicable method 'Contains' exists in type 'String'

Root Cause:

Many people are very confused about this behavior and come to the conclusion to execute some special LINQ call. Apparently it has nothing to do with missing procedure but it's just the Text or control fields set up not correctly.

This is because the Control's ConvertEmptyStringToNull (for example TextBox)  property needs to be adjusted from true to false. Without it, when nothing is typed into the field, it will go out as a null object and then it cannot find the method.

Please note that it appears that this change has to be made to all of the fields in the query. 

Fix:
  • In your LinqDataSource "Where.." editor dialog box, select the (TextBox control(s)).
  • Next find "Show Advanced Properties" link. Click this.



 Then, you will find where to change ConvertEmptyStringToNull configuration.


 Or, you can edit the configuration straight in the page's source like this;


LinqToSQL: How To do a equivalent of Like '%' "Match Everything"

Question:

How can I do a equivalent of LIKE '%' in SQL with LinqToSql?

Answer:

Simply pass an empty string "" to Contains function.

For example,

var patients = from p in ctx.Patients where PatientsName.Contains("");


Thursday, July 18, 2013

IIS 7 Page Caching May Cause Your Dynamic Page Not To Execute

I just ran into an interesting situation, which a dynamic page did not update at all even though the web call succeeded. This really puzzled us for a bit of time this afternoon, fortunately I realized what was actually happening and solved the problem. The point of this article is that if you did not have any idea what is happening under the hood, it would have puzzled you even the longest time and even make you go down the wrong path.

So, first what I was trying to do.

I wrote a very simple ASP.NET REST type application to log errors and such and the logging message came only in the URL. I tested it and worked fine.

What has happened though is that once it was put in production my colleague has noted that if the identical log message was sent repeatedly and subsequently, it stopped logging the second message and the later ones.

The program is really simple, it just parsed the URL and anything after ?m= parameter it logged that information to an SQL database along with the time the request came in. For example ?m="Process X called"

The root cause of this was that if a same message was sent then the URL would have been identical the second time. Now IIS caching mechanism thinks that since this is the same URL, it would not execute the actual ASP.NET program, but just show the page that was already generated. So in effect it did not log subsequent messages. Initially we though the SQL server has some mechanism that would prevent the same message from being logged, though that' would be totally absurd.

Then I thought that this must be due to some sort of cache optimization on the server side.

Sure enough, we have confirmed that this is actually the case, as unique messages do log, and since as soon as we added ?t= in the URL in which a sequence number incremented and then every message logged OK.

Now I have confirmed that the Server Side Page Caching is a feature in IIS and that it can be controlled in many ways. This behavior is also enabled by default.

Knowing this behavior exists will help you understand why some page update do not happen as you expect. This is especially true for dynamically generated pages.

For further information on this topic, searching for IIS Cache on your favorite search engine or on the MSDN web site.





Wednesday, June 12, 2013

Windows Visual Studio WebControl Under IE 7 Emulation Does Not Load JSON

Symptom:

Under the IE7 emulation mode of the Visual Studio WebControl, JSON does not load.  You receive 'JSON' is undefined error.

Root Cause:

JSON is not natively supported in IE7.

Workaround:

You can include JSON2 from https://github.com/douglascrockford/JSON-js/blob/master/json2.js in your script set and this will make JSON to work.




Windows Visual Studio WebControl Does Not Load the Latest JavaScript Version

Symptom

You have enabled the JavaScript capability on the WebControl using my previous artcile (read now). However, the JavaScript version stays with, for example, version 13 instead of version 17, that's standard on IE 9.

Root Cause

This appears to be due to some extra stuff in !DOCTYPE attribute of a page. By default Visual Studio 2010 new Web Forms page will add the following

!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"

It is most likely that  xhtml1-transitional.dtd is affecting the browser behavior but I am not going to verify that (you can.)

Fix

If you keep the !DOCTYPE only to just to say , in other words remove the rest of the junk in the DOCTYPE, then the JavaScript version will go up to the latest version.

The HTML5 standard requires that the DOCTYPE to only have html as its attribute.

Tuesday, June 11, 2013

Windows VisualStuduio WebBrowser Control Does Not Run JavaScript

Symptom:

You have dragged in the Web Browser Control into your Windows desktop application. Then you tried to open a page that contains JavaScript. You immediately get messages like "JSON" not found, or other sorts of script error.

You have already checked to see if JavaScript. Enable property is available but there is not that you can see.

Root Cause:

Please know the following facts;
  • By default the WebBrowser control does not support JavaScript, and also it runs in IE 7 compatibility mode.
  • The WebBrowser control is nothing but the same version if IE running on your desktop. So if your system only has the IE 8 then it will only run up to the feature of IE 8.
  • It is not true that you change the your IE's security mode the Javascript will run. Reason for this is that the security model is tied to the name of the program set up in the registry. The same settings actually control iexplore.exe as well.
  • If you are running a program via Visual Studio in debugging mode, the name of the program is different from the EXE that it produces. 
 Suggested Fixes
  • Because the program name changes depending on how you are running it, I suggest that you automate the program name detection using the  following code snippet.
The following code snippet allows you to configure the registry settings so that the web browser control will assume a proper IE mode of operation. This is by default set to IE 7.0 without JavaScript. The following example sets the IE to IE 9 emulation mode and also detects a program name you are running as.


      using Microsoft.Win32;  // DO NOT FORGET TO INCLUDE THIS ON TOP OF YOUR PROGRAM

      private static void SetIE9Feature()
        {
            try
            {  
                UInt32 FeatureCode = 9000; // for IE9, use 8000 for IE8 and 7000 for IE7 etc.   
                var asm = System.Reflection.Assembly.GetExecutingAssembly();
                var rootKey = Registry.LocalMachine;
                var sk = rootKey.OpenSubKey(@"SOFTWARE", true);
                var mk = sk.OpenSubKey(@"Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BEHAVIORS", true);
                if (mk != null)
                {
                    var p = System.AppDomain.CurrentDomain.FriendlyName;
                    mk.SetValue(p, FeatureCode, RegistryValueKind.DWord);
                }

                var mk2 = sk.OpenSubKey(@"Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION",             
                                        true);
                if (mk2 != null)
                {
                    var p = System.AppDomain.CurrentDomain.FriendlyName;
                    mk2.SetValue(p, FeatureCode, RegistryValueKind.DWord);
                }

                var m = String.Format(@"Great! Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BEHAVIORS and " +                 
                    "FEATURE_BROWSER_EMULATION modes went OK to mode {0}. Please restart the " +
                    " application for this to take effect.", 
                    FeatureCode);
                    MessageBox.Show(m);

            }
            catch(Exception ex)
            {
                var m = String.Format(@"Sorry, it's a NO GO for setting Microsoft\Internet " +
                "Explorer\Main\FeatureControl\FEATURE_BEHAVIORS and FEATURE_BROWSER_EMULATION modes. "+ 
                "Did you run as Administrator? {0}",
                    ex.ToString());
                    MessageBox.Show(m);
            }
        }

Thursday, May 09, 2013

Getting a Single Value Out of XMLElement.InnerText

Symptom:

Suppose you have the following XML (and succesfully navigated down to the first element in the line below using something like Eelement.Select(@"//element"); etc.
<element>a
<element>b
</element>
</element>
If your mind is like mine, you probably thought that
  1. Element.Value would give you "a". Element.Value actually won't give you anything.
  2. Element.InnerText would give you "a". That is not true either, it will give you "ab" since it returns all of the text of the children.
How do you extract the string "a" out of this.

First off the answer (2) is more correct one. But we forget that everything in XML are linked nodes. Therefore the Text part which comprises of "a" is technically a child node of the first element.


Tuesday, April 30, 2013

MacOS - Why It Has Became So Non-Intuitive

So I was one of the earliest people to own Apple ][ and anything they made afterwards including the Newton. I have been and I am a big fan of Apple products. But lately, I am getting to start to think, it is no longer not as intuitive as I thought it should be.

Case in point.

How can you quickly change the audio input and output.

The typical Apple Support Forum answer that, if you post it, would be that it should either be too ovbious to you, or another good one is "why would you want to do that?"

Well it so happens that in my setup, there are many input devices that are connected to my Mac. Sometimes I want input from my musical instruments and sometimes I want to input from my headset with a mic for conference calls. Sometimes I want the output to go to my stuido monitors and sometimes I want to listen to the audio with my headphones or any combinations thereof.

On Windows, things have become more consistent lately. Whatever extra stuff I need to do, just click the right mouse button.

Well, on my Mac, a click the right mouse button (and yes I am using the Magic Pad by using two-finger gesture) on top of the volume control on the menu bar does nothing.

Instead, I had to remember to Option then click.  And it requires some searching to find this out. Problematically there is nothing that interfere with right-mouse click on the audio icon on the menu bar.

So why on the Finder option click does not provide a menu?

On Windows, if you right click the "speaker" icon on the taskbar tray, it comes up with various options for audio along with "Properties" in which you can do more stuff. I feel that on Windows it has became much more consistent over the years.

I am willing to bet that if Microsoft had said that you would need to press the ALT key to get to these audio options, I know Apple fans would make a good fun out of it. And that's exactly the situation going with the Mac OS.

Apple fans, please make more demand out of them to keep it the systems most intuitive system rather than just be in so much love with it and stop protecting it just as soon as someone post anything a bit negative about its products. Things are changing rapidly and I do not want to go back to the Emilio days again.




Thursday, March 28, 2013

jQuery Ajax POST to REST WCF Returns a Bad (Status 400) Request

Problem,


Note: I have recently found out that you can do this much easier with the Microsoft Web API framework. This is a configuration hell and I will not recommend it.

I recently have started to implement a RESTful interface using the WCF in ASP.NET. The advantage of using the WCF is that on the C# side (can be a VB or even F#), the coding can be done in C# without much worries, and we can take advantage of the built-in  (de)serialization in JSON format, which is very common dealing with JavaScript.

In my situation, the client side is a JQuery running in a standard web browser. And that's where the problem begun.

A "GET" method worked quite easily, but the POST method did not work initially, and it is a rather complex issue especially with Web.Config endpoint behaviors and such.

Some Points to Check

First, most examples on the web, including the ones in the JQuery document pages, are not always correct for encoding a JSON data. The following example is the correct one that worked. All I needed was a pair of single quote surrounding the JSON data itself, and that was the key.

var p = '{ "c" : "Hello", "dt" : "2013-03-27" }';

Above structure reflects this in C#

  [DataContract (Name="PostEchoData")]
    public class PostEchoData
    {
        [DataMember (Name="c")]
        public string c
        {
            get;
            set;
        }

        [DataMember (Name="dt")]
        public string dt
        {
            get;
            set;
        }

Second, it looks like you need to use the $.ajax interface, instead of $.post because WCF side needs the content type of application/json and charset of utf-8 and decides to de-serialize the data. Without this information you will very likely get the Error status 400.  So it is essential that JSON ContentType must be specified when uploading the POST data.

You can use the following calling framework when POSTing a JSON object to WCF from your JavaScript.

Since the $.post does not (seem to) allow the explicit contentType specification, this is the reason you need to go to $.ajax call.

              var x = $.ajax(
                {
                    type: "POST",
                    contentType: "application/json; charset=utf-8",
                    url: url,
                    data: p,
                    dataType: "json",
                    success: asuccess
                }       );

Finally, there are many things you need to modify your Web.Config but there are a lot of posts about this on StackOverflow or places of that nature so I will let you figure that out.

These are probably very novice errors, nevertheless, there are a lot of posts on this on the network, so I am sure this information will help someone down the line.

P.S.: It's JSON and not JaSON!

Wednesday, March 13, 2013

LinqDataSource Bound Grid View and RowDataBound Handling

Scenario

You have bound a LinqDataSource to DataGridView.

Now you want to dynamically modify the contents of grids using RawDataBound event based on the row data, for example flag a field as RED when there is an overdue account, but you do not know how to get to the data contained in Row.DataItem

You will quickly find that DataItem is a member of DynamicClass for which there is no public property to methods to get to the data. You will also find that your debugger can display the information, and it just a row from a LINQ select statement.

Solution

A very small amount of Reflection is needed to do this work. Suppose that you had a column in the table in the LinqDataSource with the name of "CustomerGuidKey". Here is how to get at it.

   protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        var item = e.Row.DataItem;
        if (item == null) return;
        var t = item.GetType();
        PropertyInfo p = t.GetProperty("CustomerGuidKey");
        var v = (Guid) p.GetValue(item, null);
.....

Be sure to include the namespace "System.Reflection" in your code.


Wednesday, January 30, 2013

Visual Studio Debugger Slow To Start Up Due To Symbol Loads

Symptom:

Suddenly when you are debugging your application the application startup on your Visual Studio begins to crawl down to 20-30 seconds or even longer, as it starts loading symbols from all over the places for Microsoft's .NET Framework library and GACs etc.

Possible (But May Not Be Exact) Cause:

You or someone in the team have accidentally enabled Symbol loading from All Modules.

Try If Above Applies

Try this to see if it makes any difference.

On your Visual Studio, go to Debug and then Select Option and Settings...

On the left panel go down to where it says Symbols under the Debug section.

Select "Only Specified Modules" and you do not need to specify any modules at all if you are only interested in debugging modules that are in your own project.


Saturday, January 05, 2013

Dynamically Extracting SQL Fields in LinqToSQL Data Object

Problem:

I had a situation in which I get a SQL record using LinqToSQL then dynamically extract a value continued in the returned record by the field name.  For example, suppose you have a SQL Table that contains columns like "Description" or "Indication" and the caller would want to know what's contained in these field individually, also dynamically (so that in the future if a column is added, the code do not need to change.)

If you look at these database record objects that LinqToSQL generates, there is no "by-name" functions. 

Solution: 

As it turns out you can essentially "parse" break-down a C# object descriptions into arrays called MethodInfo and FieldInfo using System.Reflection. Once we know this the rest of of the idea is easy; just find the matching method or field names the user requests and dynamically access either the fields or methods.

In LinqToSQL database "row" class objects, the column values are implemented as {get; set; } methods, so instead of extracting the FieldInfo, you need to extract MethodInfo for the column field, and you get two methods get_ and set_. So if my Study table contains Description then the method to get the Description value in the column is _get_Description.

My code example below returns the value contained in the field. In order to make it easier for the user, I make the field name matching to be non-case sensitive by ToLower() the names. 


 
 
 private string FindStudyField(string Field, Guid? StudyGuidKey)
        {
            if (StudyGuidKey == null) return "";

            using (var ctx = MyLINQtoSQL.ContextFactory.NewMyDataConext())
            {

                var studies = from s in ctx.Studies
                              orderby s.StudyDateTime descending
                              where s.StudyGuidKey == StudyGuidKey
                              select s;

                if (studies.Count() == 0) return "";

                /*
                 * The following piece of code uses Reflection to get values "dynamically" 
                 * out of a LINQ data row object. In this case a Study record from a study table.
                 * LINQ values are implemented as {get; set;} methods, so we will need to 
                 * get them out as methods. This means that the field name needs to be 
                 * appended with a 'get_' to derive the proper method name that corresponds
                 * with the SQL field name.
                 * 
                 */

                Field = "get_" + Field.Trim().ToLower();

                try
                {
                    Study study = studies.First();
                    Type studyType = typeof(Study);
                    MethodInfo[] studyFields = studyType.GetMethods(BindingFlags.Public
                        | BindingFlags.Instance);

                    for (int i = 0; i < studyFields.Length; i++)
                    {
                        var fn = studyFields[i].Name.ToLower();
                        if (fn != Field) continue;
                        var v = studyFields[i].Invoke(study, null).ToString();
                        return "";
                    }
                }
                catch (Exception ex)
                {
                    return "";
                }
            }
            
            return "";
        }

Sunday, December 23, 2012

SQL  Server Mirroring Tips

A few days ago I had to fix yet another SQL Server mirroring issue.

So here are some practices I have adoped on how to make it work right. Before diving into this, though you should be very keenly aware that Mirroring uses host name based encryption just like the SSL on a web server. If the hostnames do not match against its' certificates then you will not have a connection.

Don’t Use The Servers’ Hostnames


This absolutely sounds not intuitive, but here is the deal. If you are multi-homing your server, or having a Hyper-V running on your machine, chances are you have unintentionally left the “Auto Register DNS” mode in your TCP/IP control panel. If you do not know what I am talking about then, it is very likely that you will run into this situation, since “Auto Register DNS” seems to be on by default.

Don’t bother even thinking about it. No need to understand it and no need for a full time network engineer looking out for your situation.

The deal is that the IP address to Hostname mapping can quickly go wrong as people change the IP addresses on the control panel etc. If you are running Hyper-V or multi-homing then there are more than one IP addresses assigned to a host name.

Unfortunately, the Mirroring works basically only with a pure Fully Qualified Domain Name (FQDN). Which means that a single IP address must be mapped to a single host name.

So don’t let the OS determine this for you. Ask your IT folks and create Dedicated Hostnames for your SQL Servers and have them enter those statically into their DNS, and just for an extra measure edit your on C:\Windows\System32\Drivers\Etc\Hosts file and put the FQDN and addresses of the hostnames involved in mirroring (i.e., primary, secondary and witness – note I did not say Principal, Mirror and Witness, I said primary, secondary and witness since any of primary and secondary can be a principal at any given time.)

For example you have a primary and secondary as MyServer1.mydomain.edu and MyServer2.mydomain.edu then I’d separately create MyServerSQL1.mydomain.edu and MyServerSQL2.mydomain.edu. And have those entered manually into your domain’s DNS.

Now You Have Defined the Dedicated Host Names…

Connect with the SQL Server using the FQDN of the newly defined server using the FQDN string. For example, if you have an instance called TOMORROW, connect the database as MyServer1.mydomain.edu\TOMORROW

This will ensure that subsequent mirroring configurations will use the FQDN.

Configuring for Mirroring -- Security End-Point  Setup Step

Use the newly created FQDN when establishing the security end-points to connect to other database servers. Do not connect to the original server names.

Even if you take good care in doing this, the SQL Server still decides to change the FQDN of the endpoints, and that's the very reason it breaks or mirroring not establishing right.

After the end-points are set up, DO NOT start mirroring immediately. Instead check the end-point strings to have the FQDN. Typically SQL server reverts all or some of the string to the original host name, and that’ exactly not what you want.

Half-Established Mirror Databases -- Recovery Technique

Somethings the mirroring begins to establish and fails. The mirror side goes into the "mirrored" but disconnected mode. This can happen when you may have not typed in the FQDN correctly, and after realizing that you made a mistake, you tried to re-configure the end points, then you are only to get a Database Instance is Not Online or Available message.

You may recover from this condition by
  1. Going to the mirror side
  2. Enter "ALTER YourDatabaseName SET PARTNER OFF"
If the database goes into the "Restoring" mode, and if you try to re-mirror by entering the correct FQDN and also checking the correct FQDN before starting the mirroring.