Jack @ ASP.NET

As a software engineer, I focus on .NET, especially asp.net, C#, WCF and so on, and I am also very interested in Search Engine Optimization.

Entries for the ‘Programming’ Category

Duplicate Code

Duplicate code, sometimes referred to as clones, is a cluster of code blocks that are functionally equivalent (or nearly equivalent) spanning across two or more locations within a solution. Duplicate code is expensive to maintain because:

  1. Multiplied bugs. A bug in one clone means there’s a bug in all the copies. This can lead to a continued, repeated release of previously-fixed bugs as each copy of the bug is individually discovered by a customer and then fixed by the team.
  2. Flexibility barriers. If the copied code needs to be more flexible, changes need to be made across all the copies or ideally, the copies need to be consolidated first. Unfortunately consolidation is a high-risk, error-prone, time-consuming activity.
  3. Increased ramp-up time. Copy the code and new developers trying to get up to speed will have twice as much code to read and understand. If discovered, duplicated code tends to be harder to understand than normal code because the reader must not only understand functionality, but also understand the reason behind the duplication.

Pipeline in PowerShell

PowerShell uses a pipeline for all command entries, which feeds the results of the preceding command directly into the subsequent command. The pipeline is active even when you enter only a single command because PowerShell always automatically adds the Out-Default cmdlet at the pipeline’s end so that it always results in a two-member instruction chain.

Single command results are passed as objects. The cmdlets can filter, sort, compare, measure, expand, and restrict pipeline elements. All cmdlets accomplish this on the basis
of object properties. In the process, the pipeline distinguishes between sequential and streaming modes. In streaming mode, command results are each collected, and then passed in mass onto the next command. Which mode you use depends solely on the pipeline commands used. Output cmdlets dispose of output. If you specify none, PowerShell automatically uses Out-Host to output the results in the console. However, you could just as well send results to a file or printer.

All output cmdlets convert objects into readable text while formatting cmdlets are responsible for conversion. Normally, formatting cmdlets convert only the most important, but if requested, all objects into text. The Extended Type System (ETS) helps convert objects into text. The ETS uses internal records that specify the best way of converting a particular object type into text. If an object type isn’t in an ETS internal record, the ETS resorts to a heuristic method, which is guided by, among other things, how many properties are contained in the unknown object.

In addition to traditional output cmdlets, export cmdlets store objects either as comma-separated lists that can be opened in Excel or serialized in an XML format. Serialized objects can be comfortably converted back into objects at a later time. Because when exporting, in contrast to outputting, only plain object properties, without cosmetic formatting, are stored so that no formatting cmdlets are used.

Interactive PowerShell

The PowerShell console runs all kinds of commands interactively: you enter a command, and the console will more or less immediately return the results. If you enter a command and execute it by pressing (Enter), PowerShell looks for the command in this order:

  • Alias: It will first look to see if your command corresponds to an alias. If it does, the command will be executed that the alias designates. You can "overwrite" any other command with an alias by using the cmdlet Set-Alias because aliases have highest priority.
  • Function: If no alias could be found, PowerShell looks next for a function, which resembles an alias, but can consist of many PowerShell instructions. You can wrap commands, including frequently used arguments, in functions.
  • Cmdlet: If it’s not possible to find a function, PowerShell looks for cmdlets, which are internal PowerShell commands that conform to strict naming rules and whose names always consist of a verb and a noun.
  • Application: PowerShell looks first for a cmdlet, and if it can’t find any, it then searches for external commands in the subdirectories specified in the Path environment variables. If you’d like to use a command at some other location, then you must specify a relative or absolute path name.
  • Script: If PowerShell can’t find any external commands, it looks next for a script with the file extension ".ps1". However, scripts are executed only when restrictions of the ExecutionPolicy are eased, allowing PowerShell scripts to be run.
  • Files: If no PowerShell scripts are found, PowerShell keeps looking for other files. PowerShell
    reports an error if your command doesn’t match any files.

Versioning and optional parameters

The restrictions on default values for optional parameters may remind you of the restrictions on const fields or attribute values, and they behave very similarly. In both cases, when the compiler references the value, it copies it directly into the output. The generated IL acts exactly as if your original source code had contained the default value. This means if you ever change the default value without recompiling everything that references it, the old callers will still be using the old default value. To make this concrete, imagine this set of steps:

  1. Create a class library  with a class like this:
    public class MyDemo
    {
    	public static void PrintValue(int value = 10)
    	{
    		System.Console.WriteLine(value);
    	}
    }
  2. Create a console application (Application.exe) that references the class library:
    public class Program
    {
    	static void Main()
    	{
    		MyDemo.PrintValue();
    	}
    }
  3. Run the application—it’ll print 10, predictably.
  4. Change the declaration of PrintValue as follows, then recompile just the class library:
    public static void PrintValue(int value = 20)
  5. Rerun the application—it’ll still print 10. The value has been compiled directly into the executable.
  6. Recompile the application and rerun it—this time it’ll print 20.

This versioning issue can cause bugs that are hard to track down, because all the code looks correct. Essentially, you’re restricted to using genuine constants that should never change as default values for optional parameters. There’s one benefit of this setup: it gives the caller a guarantee that the value it knew about at compile-time is the one that’ll be used. Developers may feel more comfortable with that than with a dynamically computed value, or one that depends on the version of the library used at execution time.

Of course, this also means you can’t use any values that can’t be expressed as constants anyway—you can’t create a method with a default value of “the current time,” for example.

Call SQLCMD to run SQL script via C#

Usually, we need to call some sql script to update our database in our application(C#), and it is a good way to call SQLCMD to execute the sql scripts. One important reason is that our scripts always contains the GO statement which is is not a Transact-SQL statement; it is a command recognized by the sqlcmd and osql utilities and SQL Server Management Studio Code editor. Since the SQLCMD and SQL Server Management Studio will do the same thing, the scripts edited by SQL Server Management Studio will be 100% supported by SQLCMD.

Here is a block of code to call SQLCMD:

 

string tmpFile = Path.GetTempFileName();

string argument = string.Format(@" -S {0} -d {1} -i ""{2}"" -o ""{3}""",
    ServerName, DatabaseName, fileName, tmpFile);

// append user/password if not use integrated security
if (!connection.IsIntegratedSecurity)
    argument += string.Format(" -U {0} -P {1}", User, Password);

var process = Process.Start("sqlcmd.exe", argument);
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.Start();
while (true)
{
    // wait for the process exits. The WaitForExit() method doesn't work
    if (process.HasExited)
        break;
    Thread.Sleep(500);
}

Incorrect Syntax near ‘GO’ while using SqlCommand.ExecuteNonQuery()

GO is not a Transact-SQL statement; it is often used in T-SQL code. Go causes all statements from the beginning of the script or the last GO statement (whichever is closer) to be compiled into one execution plan and sent to the server independent of any other batches. SQL Server utilities interpret GO as a signal that they should send the current batch of Transact-SQL statements to an instance of SQL Server. The current batch of statements is composed of all statements entered since the last GO, or since the start of the ad hoc session or script if this is the first GO.

GO Statement must be written in new line as it is not T-SQL command. T-SQL statement can not occupy the same line as GO. GO statement can contain comments.

select * from tableA
go
insert into tablea(MyValue) values(‘aaa’)
go
select * from tableA
go

The above sql script for example, will give you a ‘Incorrect Syntax near GO’ exception. the solution to this is remove the ‘GO’ statement.