Posts tagged ‘C#.NET’

Use ExecuteScalar to insert a database row and return the primary key

I suspect that just about every developer who has had to work with SQL Server has faced this issue. You need to insert a bunch of related records, some of which depend on other records being in the database first. I stumbled on a way to use ExecuteScalar to insert a database row and return the primary key with one call.

To do this, you just add this to the end of your INSERT statement:

SELECT Scope_Identity();

This SQL Server function returns the primary key of the last row that was added to the database with a primary key column. For my instance, I have a SqlText class that encapsulates a lot of the System.Data.Client functionality, so my code looks like this. (I have omitted most of the fields so that this code would be shorter.)

// table 'BillingAddresses' has an integer primary key, auto generated, identity
// 'addressLine1' below refers to a string variable containing line 1 of the address
var sqlString = "insert into BillingAddresses (Line1) values (@Line1); SELECT Scope_Identity();";
var newBillingAddressID = SqlText.ExecuteScalar(sqlString, new { Line1 = addressLine1 });

However, if you are using the standard System.Data.Client namespace, your code would then look like this:

// table 'BillingAddresses' has an integer primary key, auto generated, identity
// 'conn' below refers to an opened instance of a SqlConnection
// 'addressLine1' below refers to a string variable containing line 1 of the address
var sqlString = "insert into BillingAddresses (Line1) values (@Line1); SELECT Scope_Identity();";
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.Add("@Line1", SqlDbType.VarChar);
cmd.Parameters["@Line1"].Value = addressLine1;
var newBillingAddressID = cmd.ExecuteScalar();

Mac Visual Studio Error: Address already in use

I have started to use the Mac version of Visual Studio more and more, and I must say I like it very much. But that does not mean it is not without its sharper edges.

Once in a while, when I am working on .NET web applications, something funky happens and when I try to run the project locally, I get the message:

Error: Address already in use

Here is how to fix this issue without having to go through some kind of insane reboot and/or ritual sacrifice.

First, find the process ID of the offending application in the terminal with this command, where you will replace 3306 with the port number that your local application runs on:

sudo lsof -iTCP -sTCP:LISTEN -P | grep :3306

This should give you the application and process ID (the first two items on the line) of the offender. Then, you enter this command, replacing 1234 with the second item from the data that the lsof command spit out:

kill -9 1234

BTW, Happy Belated 100th Birthday to the Grand Canyon. OK, not the actual canyon, but the National Park, which was designated such 100 years and 1 day ago. My advice to everyone is to stay at the El Tovar and eat breakfast at the restaurant, the sunrise is pretty astounding.

C# .NET simple Async Await example from console application Main

I did a couple of posts a few years back about doing async/await in VB.NET, and now I had need of doing something similar with a C# .NET console application.

Here is what I put together to get it working. This is the contents of the main class for a C# .NET console application, but you should be able to adapt the code to whatever need you have.

using System;
using System.Net.Http;
using System.Threading.Tasks;
 
namespace SimpleAsync
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Simple async");
 
            try
            {
                LengthyAsyncTask().Wait();
            }
            catch (Exception ex)
            {
                Console.WriteLine("There was an exception: " + ex.ToString());
            }
 
            Console.WriteLine("Press enter to quit application...");
            Console.ReadLine();
        }
 
        static async Task LengthyAsyncTask()
        {
            var response = await GetWebPage("https://www.dosomethinghere.com");
            Console.WriteLine("Response: " + response);
            // do something here with the response
        }
 
        static async Task<string> GetWebPage(string url)
        {
            var client = new HttpClient();
            var response = await client.GetAsync(url);
            var responseString = await response.Content.ReadAsStringAsync();
            return responseString;
        }
    }
}

BTW, Happy Anniversary to The Wall and Thriller, both seminal works of artistry from music’s golden age, released this day in 1979 and 1982, respectively. Darkness falls across the land… And how can you eat your pudding when you haven’t eaten your meat?

Visual Studio 2017 launches to a black or invisible screen, part 2

It turns out that disabling the Intel and Nvidia drivers on my Windows notebook computer are not really sufficient to fix the issue when Visual Studio 2017 launches to a black or invisible screen, as by doing this, I lost the ability to connect an external monitor to the HDMI port on the computer. Super bummer.

A bit more digging through the interwebs led me to this answer to a question on Stack Overflow:

White screen while opening visual studio

Basically, I re-enabled the Intel and Nvidia display options, then opened the Nvidia Control Panel by right-clicking on the desktop, selected Manage 3D Settings and changed the Preferred graphics processor selection from Auto-select to High-performance NVIDIA processor. Now everything is back to working the way I would like it to.

BTW, there are no birthdays today worthy of mention (cough, cough), so Happy International Left Handers Day!

Visual Studio 2017 launches to a black or invisible screen

So I am working along on a .NET project in Visual Studio 2017 on my Windows 10 Pro laptop, and all of a sudden when I launch the application, I get either a black window where the IDE should be, or the window area is transparent and I just see a shadow of the window edge. Very frustrating, as it was working fine the day before.

Finally I tracked it down to some kind of problem with a display driver. My laptop came preloaded with Intel and Nvidia display drivers and control panels, so I went into the computer management and disabled both the Intel and Nvidia display adapters. After rebooting, my screen still works, and magically I can see Visual Studio when I fire it up. Sure, there are some negatives to this, such as not being able to change the display resolution of the laptop panel, as the only choice in the dropdown is the native resolution of the panel. But at least I am able to once again get stuff done.

BTW, Happy Birthday to Joe Satriani. I hope Joe and the band make a tour stop somewhere near central Ohio soon. I saw the G3 tour last year in Cleveland, but there wasn’t enough Joe.

LINQ to SQL DBML file shows up as XML code in Visual Studio Community 2017

I have a project from a few years ago that I am looking back into again, and while it builds just fine in Visual Studio Community 2017, when I open the DBML file, I get a big XML file instead of a nice design surface with the data tables.

The solution to this issue is to install the correct component to handle this type of file. To do this, you need to exit Visual Studio IDE and then launch the Visual Studio Installer. Once there, click Modify, click the Individual components tab at the top, scroll down to the Code tools section, select LINQ to SQL tools so that there is a check mark next to it, and click the Modify button at the bottom right corner of the window. Once this finishes and you go back into Visual Studio, the DBML file should now show up as a design surface instead of XML source code.

BTW, a posthumous Happy Birthday to Gilda Radner, who left us far too soon.

Plain ol’ XML

So let’s say you are working on an application in the .NET sphere of influence, and you have an object that you want to turn into XML. However, you shoot it through an XmlSerializer and you think you are done.

Ugh, what’s all that cruft in the XML stream?

Well there are some options you can play with to get rid of the extra stuff and just get plain ol’ XML. Here is a code snippet, where you will pass in your own object instead of the generic Order as shown below:

public String GetPlainOldXML(Order order)
{
    var emptyNamepsaces = new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty });
    var settings = new XmlWriterSettings();
    settings.OmitXmlDeclaration = true;
 
    XmlSerializer xsSubmit = new XmlSerializer(typeof(Order));
    var xmlString = "";
    using (var sww = new StringWriter())
    {
        using (XmlWriter writer = XmlWriter.Create(sww, settings))
        {
            xsSubmit.Serialize(writer, order, emptyNamepsaces);
            xmlString = sww.ToString();
        }
    }
 
    return xmlString;
}

BTW, Happy Birthday to Leslie West of Mountain fame.

Error 404 on web service with map route

If you are getting an error 404 on your web service with a map route decorator on your methods, you might want to check your IIS settings to make sure that it is configured correctly.

Apparently, your app pool must be set up in integrated mode as opposed to classic mode in order for the routing to work.

BTW, Happy 10th Anniversary to the iPhone.

The final word on .NET background processing (for now)

While snooping around for information on .NET background processing, I came across a bunch of interesting articles by .NET MVP Stephen Cleary that go into great detail about using Task.Run vs. a BackgroundWorker control. Here is the link to the introduction of the series of articles:

Task.Run vs BackgroundWorker: Intro

BTW, I am impressed so far with the content that was revealed at the WWDC 2015 conference. I have been going through the presentations and, while there were no “knock your socks off” moments, there is still a ton of great stuff that they are packing into the new versions of iOS, OS X, and watchOS.

Cross a bridge at night

OK, here is a scenario. Four people on a journey together need to cross a bridge at night as quickly as possible. Among the four of them, they have one flashlight. They cannot continue their journey until all four reach the other side together. Since the bridge is narrow and slippery, and it is pitch black out being night and all, they decide to have two people cross with the flashlight, then one person returns with the flashlight back to the original side, and they continue until everyone is on the other side.

Oh, and also, the people can all walk at different paces, so when two people cross together, it takes them the amount of time that it takes the slower person to cover the distance.

For example, let’s say that the four people that need to cross can cover the distance of the bridge in 1 minute, 2 minutes, 5 minutes, and 10 minutes. What would be the shortest possible time?

The naive solution would be to have the 1 minute person be the primary flashlight runner and send them with the 2 minute person, return, then the 5 minute person, return, and finally cross with the 10 minute person, for a grand total of 19 minutes.

Now of course this is not the optimal solution, but more on that in a minute.

So how would we design an algorithm to solve this problem? Conventional wisdom says to create some kind of tree where you iterate through all of the possible combinations of initial crossings, then off those branches, combinations of reverse crossings, etc. Then once the tree is built, you can walk to all the branch tips and calculate the times, and then just display the shortest time.

But why do something logical? With all this computing power, I say that we implement my favorite algorithm for producing solutions to problems… The Monte Carlo method.

Here is the code for a C# .NET console app I threw together to solve this issue:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace BridgeAtNight
{
    public class BridgeState
    {
        public List<int> peopleOnLeft;
        public List<int> peopleOnRight;
        public int totalTime;
        public string peopleMovement;
 
        public BridgeState(int[] people)
        {
            totalTime = 0;
            peopleMovement = "";
            peopleOnLeft = new List<int>(people);
            peopleOnRight = new List<int>();
        }
 
        public void MoveLeftToRight(int leftToRight1, int leftToRight2)
        {
            peopleMovement = peopleMovement + string.Format("{0}>> {1}>> ", leftToRight1, leftToRight2);
            totalTime += Math.Max(leftToRight1, leftToRight2);
 
            peopleOnRight.Add(leftToRight1);
            peopleOnRight.Add(leftToRight2);
            peopleOnRight.Sort();
 
            peopleOnLeft.Remove(leftToRight1);
            peopleOnLeft.Remove(leftToRight2);
        }
 
        public void MoveRightToLeft(int rightToLeft)
        {
            peopleMovement = peopleMovement + string.Format("{0}<< ", rightToLeft);
            totalTime += rightToLeft;
 
            peopleOnLeft.Add(rightToLeft);
            peopleOnLeft.Sort();
 
            peopleOnRight.Remove(rightToLeft);
        }
 
        public void SolveWithNaivete()
        {
            peopleOnLeft.Sort();
            while (peopleOnLeft.Count > 1)
            {
                // move 2 people from the left to the right
                int leftToRight1 = peopleOnLeft[0];
                int leftToRight2 = peopleOnLeft[1];
                MoveLeftToRight(leftToRight1, leftToRight2);
 
                // move 1 person from right to left if there are any remaining people on the left
                if (peopleOnLeft.Count > 0)
                {
                    int rightToLeft = peopleOnRight[0];
                    MoveRightToLeft(rightToLeft);
                }
            }
 
            Console.WriteLine("Solution with naivete:");
            Console.WriteLine(string.Format("Time: {0} minutes", totalTime));
            Console.WriteLine(string.Format("Sequence: {0}", peopleMovement));
        }
 
        public void SolveRandomly()
        {
            Random rnd = new Random();
            while (peopleOnLeft.Count > 1)
            {
                // move 2 people from the left to the right
                var leftToRightRandom = peopleOnLeft.OrderBy(x => rnd.Next()).Take(2).ToList();
                int leftToRight1 = leftToRightRandom[0];
                int leftToRight2 = leftToRightRandom[1];
                MoveLeftToRight(leftToRight1, leftToRight2);
 
                // move 1 person from right to left if there are any remaining people on the left
                if (peopleOnLeft.Count > 0)
                {
                    var rightToLeftRandom = peopleOnRight.OrderBy(x => rnd.Next()).Take(1).ToList();
                    int rightToLeft = rightToLeftRandom[0];
                    MoveRightToLeft(rightToLeft);
                }
            }
        }
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            BridgeState naiveBridgeState = new BridgeState(new int[] { 1, 2, 5, 10 });
            naiveBridgeState.SolveWithNaivete();
 
            List<string> bestTimeResults = new List<string>();
            int bestTime = 999999;
            for (int idx = 1; idx < 1000000; idx++)
            {
                BridgeState randomBridgeState = new BridgeState(new int[] { 1, 2, 5, 10 });
                randomBridgeState.SolveRandomly();
                if (randomBridgeState.totalTime < bestTime)
                {
                    Console.WriteLine(string.Format("Better random solution found in pass {0}:", idx));
                    Console.WriteLine(string.Format("Time: {0} minutes", randomBridgeState.totalTime));
                    Console.WriteLine(string.Format("Sequence: {0}", randomBridgeState.peopleMovement));
                    bestTime = randomBridgeState.totalTime;
                    bestTimeResults = new List<string>();
                    bestTimeResults.Add(randomBridgeState.peopleMovement);
                }
                else if (randomBridgeState.totalTime == bestTime)
                {
                    if (!bestTimeResults.Contains(randomBridgeState.peopleMovement))
                    {
                        Console.WriteLine(string.Format("Sequence: {0}", randomBridgeState.peopleMovement));
                        bestTimeResults.Add(randomBridgeState.peopleMovement);
                    }
                }
            }
 
            Console.WriteLine("Press any key to exit the application");
            Console.ReadKey();
        }
    }
}

There are undoubtedly some optimizations I can make to this code above, such as ordering the times in the MoveLeftToRight function. However, I was kind of surprised to see this run, as sometimes the optimal solution of 17 minutes was found in the first few thousand random walk throughs, and other times it would take a few hundred thousand walk throughs before the 17 minute solution was found. To me, it did not seem like there were enough different combinations that would make it so difficult to randomly find the solution.

For those who cannot/will not run this code, the crux of the biscuit, given the times of the walkers above (1 minute, 2 minutes, 5 minutes, and 10 minutes), is to send the slowest people across together once there is someone faster on the other side. Or in other words, first send 1 and 2 across, then have 1 come back. Then, send 5 and 10 across, and have 2 come back. Then 1 and 2 make the final crossing.

BTW, Happy Talk Like A Pirate Day today.