Introduction
Like most of you probably do, I have a local database server for development, and a production server that's used when the (MVC) app goes live. This means that you probably have two at least two connection strings in the Web.config file. This is how I resolve it so that I don't have to remember to use the correct connection string. Personally, I have THREE possible connection strings - DefaultConnect, DevConnection, and WorkConnection.
The Code
In my DbConext-derived class, I have the following static properties:
public static bool IsLocalHost
{
get
{
return System.Web.HttpContext.Current.Request.Url.Host.IsLike("%localhost%");
}
}
public static string connectionName
{
get
{
string name = "name=DefaultConnection";
if (HttpContext.Current != null)
{
name = string.Concat("name=",(IsLocalHost)
? "DevConnection"
: "DefaultConnection";
}
else
{
name = "name=DevConnection";
}
return name;
}
}
And my context object's constructor looks like this:
public ICSContext() : base(connectionName)
{
if (HttpContext.Current != null)
{
...
}
}
What I found was that when you run update-database in the Nuget console, an exception would be thrown if the HttpContext.Current object was null, which it would be if you're running update_database. Because of this, I had to check to make sure it wasn't null when setting the static property.
Another point of concern is that if you use authentication in your web app (and have mutiple possible connection strings, you'll also need to include similar code in the ApplicationDbContext. At the end of the connectionName property, remember to remove "name=" from the name variable.
You may also have noticed the same check inside the constructor. In my case, I'm setting mapped paths for default images, and that requires use of the HttpContext.Current object (which might be null). It was therefore necessary for me to put the same check in the constructor.
The IsLike method in the property is an extension method I've been using for years. It performs the same functionality as the T-SQL Like function, and uses the same wildcard notations as well. I've included it below if you're interested in using it.
public static bool IsLike(this string str, string pattern)
{
if (string.IsNullOrEmpty(str) || string.IsNullOrEmpty(pattern))
{
return false;
}
bool isMatch = true;
bool isWildCardOn = false;
bool isCharWildCardOn = false;
bool isCharSetOn = false;
bool isNotCharSetOn = false;
bool endOfPattern = false;
int lastWildCard = -1;
int patternIndex = 0;
char p = '\0';
List<char> set = new List<char>();
for (int i = 0; i < str.Length; i++)
{
char c = str[i];
endOfPattern = (patternIndex >= pattern.Length);
if (!endOfPattern)
{
p = pattern[patternIndex];
if (!isWildCardOn && p == '%')
{
lastWildCard = patternIndex;
isWildCardOn = true;
while (patternIndex < pattern.Length && pattern[patternIndex] == '%')
{
patternIndex++;
}
p = (patternIndex >= pattern.Length) ? '\0' : p = pattern[patternIndex];
}
else if (p == '_')
{
isCharWildCardOn = true;
patternIndex++;
}
else if (p == '[')
{
if (pattern[++patternIndex] == '^')
{
isNotCharSetOn = true;
patternIndex++;
}
else
{
isCharSetOn = true;
}
set.Clear();
if (pattern[patternIndex + 1] == '-' && pattern[patternIndex + 3] == ']')
{
char start = char.ToUpper(pattern[patternIndex]);
patternIndex += 2;
char end = char.ToUpper(pattern[patternIndex]);
if (start <= end)
{
for (char ci = start; ci <= end; ci++)
{
set.Add(ci);
}
}
patternIndex++;
}
while (patternIndex < pattern.Length && pattern[patternIndex] != ']')
{
set.Add(pattern[patternIndex]);
patternIndex++;
}
patternIndex++;
}
}
if (isWildCardOn)
{
if (char.ToUpper(c) == char.ToUpper(p))
{
isWildCardOn = false;
patternIndex++;
}
}
else if (isCharWildCardOn)
{
isCharWildCardOn = false;
}
else if (isCharSetOn || isNotCharSetOn)
{
bool charMatch = (set.Contains(char.ToUpper(c)));
if ((isNotCharSetOn && charMatch) || (isCharSetOn && !charMatch))
{
if (lastWildCard >= 0)
{
patternIndex = lastWildCard;
}
else
{
isMatch = false;
break;
}
}
isNotCharSetOn = isCharSetOn = false;
}
else
{
if (char.ToUpper(c) == char.ToUpper(p))
{
patternIndex++;
}
else
{
if (lastWildCard >= 0)
{
patternIndex = lastWildCard;
}
else
{
isMatch = false;
break;
}
}
}
}
endOfPattern = (patternIndex >= pattern.Length);
if (isMatch && !endOfPattern)
{
bool isOnlyWildCards = true;
for (int i = patternIndex; i < pattern.Length; i++)
{
if (pattern[i] != '%')
{
isOnlyWildCards = false;
break;
}
}
if (isOnlyWildCards)
{
endOfPattern = true;
}
}
return (isMatch && endOfPattern);
}
History
05 Jan 2018 - Updated static properties to reflect weirdness encountered with the "update-database" command. It woud throw "can't connect to the database" and/or "database already exists" exceptions.
11 Nov 2017 - Initial post