Thursday, January 22, 2015

LINQ Joins

Use Inner Join when you know you've got a match:

var innerJoinQuery =
    from category in categories
    join prod in products on category.ID equals prod.CategoryID
    select new { ProductName = prod.Name, Category = category.Name }; //produces flat sequence


Use Group Join when you want to see associated records in another set, for example:

var innerGroupJoinQuery =
    from category in categories
    join prod in products on category.ID equals prod.CategoryID into prodGroup
    select new { CategoryName = category.Name, Products = prodGroup }; 

You can then perform a sub-query using that group if you want to, e.g.

var innerGroupJoinQuery2 =
    from category in categories
    join prod in products on category.ID equals prod.CategoryID into prodGroup
    from prod2 in prodGroup
    where prod2.UnitPrice > 2.50M
    select prod2;

When you Left-Outer Join all the elemtns in the left source sequence are returned even if no matches are found in the right sequence. We use 'DefaultIfEmpty' to provide a NULL or a default value for the right-side element to produce if a left-side element has no matches. You can use null as the default or you can specify your own, e.g.

var leftOuterJoinQuery =
    from category in categories
    join prod in products on category.ID equals prod.CategoryID into prodGroup
    from item in prodGroup.DefaultIfEmpty(new Product { Name = String.Empty, CategoryID = 0 })
    select new { CatName = category.Name, ProdName = item.Name };

See here for more info: https://msdn.microsoft.com/en-us/library/bb311040.aspx

Wednesday, April 02, 2014

Check for duplicates SQL

SELECT
    contentid, contenttypefieldid, COUNT(*)
FROM
    contentvalue
GROUP BY
    contentid, contenttypefieldid
HAVING
    COUNT(*) > 1

Wednesday, February 19, 2014

An old one, but worth remembering...

Resetting the identity value of any SQL table is as easy as follows:

USE AdventureWorks2012;
GO
DBCC CHECKIDENT ('Person.AddressType', RESEED, 10);
GO
 
http://technet.microsoft.com/en-us/library/ms176057.aspx
 
 

Friday, December 06, 2013

Routing

When adding custom routing in MVC, any custom routing must go BEFORE the default. For example:

public static void RegisterRoutes(RouteCollection routes)
  {
   routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 
            routes.MapRoute(
                 name"Zing",
                 url"zing/{type}/{p}",
                 defaultsnew { controller = "zing"action = "Index"type = UrlParameter.Optional }
             );
 
   routes.MapRoute(
    name"Default",
    url"{controller}/{action}/{id}",
    defaultsnew { controller = "Home"action = "Index"id = UrlParameter.Optional }
   );
  }

Tuesday, December 03, 2013

ToTitleCase method

The following lets you format a whole string in Title format; for example 'the news today' becomes 'The News Today' when applied. string val = new CultureInfo("en-GB", false).TextInfo.ToTitleCase(val as String);

Wednesday, March 06, 2013

Code Prettifier

For a long time, I've been intending to make use of a good code "prettifier" - something which keeps the formatting of code when you blog it and that provides appropriate contrast on the page. I have discovered the "Blogger Code Prettifier" and have followed instructions to install it on my own blog. From what I can see so far, the results are good!
Check it out here

And here's what it can do!

        static void Main(string[] args)
        {
            CopyObjectsUsingAutoMapper();
            Console.ReadLine();
        }

The joy of Auto-Mapper

Auto-Mapper solves a common problem - its mission is to make code that's used to map one object to another, obsolete. Its own website summarises the vision of the product adequately:

"AutoMapper is a simple little library built to solve a deceptively complex problem - getting rid of code that mapped one object to another. This type of code is rather dreary and boring to write, so why not invent a tool to do it for us?"

http://automapper.org/

I decided to throw together a really quick example.

First, I defined two identically built, but differently named, classes:

public class AltPlanA
    {
        public string Name { get; set; }
        public int FirstRowNumber { get; set; }
        public int LastRowNumber { get; set; }
        public string FirstRowLetter { get; set; }
        public string LastRowLetter { get; set; }
    }

    public class AltPlanB
    {
        public string Name { get; set; }
        public int FirstRowNumber { get; set; }
        public int LastRowNumber { get; set; }
        public string FirstRowLetter { get; set; }
        public string LastRowLetter { get; set; }
    }


Then, in a separate class, I wrote some mapping logic:

    public class AutoMapEx
    {
        public AutoMapEx()
        {

        }

        public AltPlanB DoMapping()
        {
            // Create the map
            Mapper.CreateMap();

            // Define source (this might, for example, come back from a DB)
            AltPlanA planA = new AltPlanA()
            {
                FirstRowLetter = "A",
                FirstRowNumber = 1,
                LastRowLetter = "Z",
                LastRowNumber = 10,
                Name = "My Plan"
            };

            // Copy to another object
            AltPlanB planB = Mapper.Map(planA);
            return planB;
        }
    }

I wanted to see the result of my mapping - to ensure it was working correctly - in a console window. To facilitate this, I decided to override the ToString() method in my AltPlanB class, like so:

  public override string ToString()
  {
   return "Name : " + Name + "\nFirstRowLetter: " + FirstRowLetter +
    "\nFirstRowNumber: " + FirstRowNumber.ToString()
    + "\nLastRowLetter: " + LastRowLetter
    + "\nLastRowNumber: " + LastRowNumber;
  }

My new AltPlanB class looked like this:

    public class AltPlanB
    {
        public string Name { get; set; }
        public int FirstRowNumber { get; set; }
        public int LastRowNumber { get; set; }
        public string FirstRowLetter { get; set; }
        public string LastRowLetter { get; set; }


        public override string ToString()
        {
            return "Name : " + Name + "\nFirstRowLetter: " + FirstRowLetter +
                "\nFirstRowNumber: " + FirstRowNumber.ToString()
                + "\nLastRowLetter: " + LastRowLetter
                + "\nLastRowNumber: " + LastRowNumber;
        }
    }

Then I wrote some simple calling code on the Console side:

        static void CopyObjectsUsingAutoMapper()
        {
            AutoMapEx mapper = new AutoMapEx();
            AltPlanB bPlan = mapper.DoMapping();
            Console.WriteLine(bPlan.ToString());            
        }

Then I called this from my Main method:

        static void Main(string[] args)
        {            
            CopyObjectsUsingAutoMapper();
            Console.ReadLine();
        }

Running the application produced the following output:


Going Further

Above is quite a straightforward example, but Auto-Mapper can go much further than that, for example objects do not necessarily have to be identical in order to map. By default, AM matches like for like (name and variable type) to do its mapping, but there are other possibilities too. See https://github.com/AutoMapper/AutoMapper/wiki to read up on what those possibilities are.

Monday, March 04, 2013

Accessing a TFS file that has not been checked in (by someone other than you)

In the scenario where a member of your team has checked out a file, disappeared from the company, thus rendering their profile/machine unusable, take the following steps to rectify the situation:


  1. Open a Visual Studio command prompt
  2. Type the following: tf undo /workspace:OtherUserWorkSpace;OtherUser $/Project/ItemName.cs


Replace 'OtherUserWorkspace' with the workspace name where the file is checked out (i.e. the user's computer name)
Replace 'OtherUser' with the username that has checked out the file
Replace '$/Project/ItemName.cs' with the full path (including all namespaces) with the file that needs to be undone

Example:

tf undo /workspace:WRK0130-PC;rbobby $/MISV2/www/Web.config.

You'll get an error such as the following when you first attempt to access the file:




Dev Notes

Fixes to common .NET problems, as well as information on .NET features and solutions to common problems that are not language-specific.

Dev Notes

Fixes to common .NET problems, as well as information on .NET features and solutions to common problems that are not language-specific.

Z