Archives

Archives / 2010 / April
  • LINQ and Aggregate function

    LINQ also provides with itself important aggregate function. Aggregate function are function that are applied over a sequence like and return only one value like Average, count, sum, Maximum etc…
    Below are some of the Aggregate functions provided with LINQ and example of their implementation.

    Count

        int[] primeFactorsOf300 = { 2, 2, 3, 5, 5 };

        int uniqueFactors = primeFactorsOf300.Distinct().Count();

    The below example provided count for only odd number.

        int[] primeFactorsOf300 = { 2, 2, 3, 5, 5 };

        int uniqueFactors = primeFactorsOf300.Distinct().Count(n => n%2 = 1);

     

    Sum


        int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };   

        double numSum = numbers.Sum();

     

    Minimum

     

        int minNum = numbers.Min();


    Maximum

     

        int maxNum = numbers.Max();

    Average

     

        double averageNum = numbers.Average();

     

    Aggregate

     

        double[] doubles = { 1.7, 2.3, 1.9, 4.1, 2.9 };

        double product = doubles.Aggregate((runningProduct, nextFactor) => runningProduct * nextFactor);

     

    Vikram

  • Working with Joins in LINQ

    While working with data most of the time we have to work with relation between different lists of data. Many a times we want to fetch data from both the list at once. This requires us to make different kind of joins between the lists of data.

    LINQ support different kinds of join

    Inner Join

        List<Customer> customers = GetCustomerList();

        List<Supplier> suppliers = GetSupplierList();

     

        var custSupJoin =

            from sup in suppliers

            join cust in customers on sup.Country equals cust.Country

            select new { Country = sup.Country, SupplierName = sup.SupplierName, CustomerName = cust.CompanyName };


    Group Join – where By the joined dataset is also grouped.


        List<Customer> customers = GetCustomerList();

        List<Supplier> suppliers = GetSupplierList();

     

        var custSupQuery =

            from sup in suppliers

            join cust in customers on sup.Country equals cust.Country into cs

            select new { Key = sup.Country, Items = cs };


    We can also work with the Left outer join in LINQ like this.


        List<Customer> customers = GetCustomerList();

        List<Supplier> suppliers = GetSupplierList();

     

        var supplierCusts =

            from sup in suppliers

            join cust in customers on sup.Country equals cust.Country into cs

            from c in cs.DefaultIfEmpty()  // DefaultIfEmpty preserves left-hand elements that have no matches on the right side

            orderby sup.SupplierName

            select new { Country = sup.Country, CompanyName = c == null ? "(No customers)" : c.CompanyName,

                         SupplierName = sup.SupplierName};

    Vikram

  • 17 new features in Visual Studio 2010

    Visual studio 2010 has been released to RTM a few days back. This release of Visual studio 2010 comes with a big number of improvements on many fronts. In this post I will try and point out some of the major improvements in Visual Studio 2010.

    1)      Visual studio IDE Improvement. Visual studio IDE has been rewritten in WPF. The look and feel of the studio has been improved for improved readability. Start page has been redesigned and template so that anyone can change the start page as they wish.

    2)      Multiple Monitor - Support for Multiple Monitor was already there in Visual studio. But in this edition it has been improved as much that we can now place the document, design and code window outside the IDE in another monitor.

    3)      ZOOM in Code Editor – Making the editors in WPF has made significant improvement for them. The best one that I like is the ZOOM feature. We can now zoom in the code editor with the help of the ctrl + Mouse scroll. The zoom feature does not work on the Design surface or windows with icon like solution view and toolbox.

    4)      Box Selection - Another Important improvement in the Visual studio 2010 is the box selection. We can select a rectangular by holding down the Alt Key and selecting with mouse.  Now in the rectangular selection we can insert text, Paste same code in different line etc. This is helpful if you want to convert a number of variables from public to private etc…

    5)      New Improved Search – One of the best productivity improvements in Visual studio 2010 is its new search as you type support. This has been done in the Navigate To window which can be brought up by pressing (Ctrl + ,). The navigate To windows also take help of the Camel casing and will be able to search with the help of camel casing when character is entered in upper case. For example we can search AOH for AddOrederHeader.

    6)      Call Hierarchy – This feature is only available to the Visual C# and Visual C++ editor. The call hierarchy windows displays the calls made to and from (yes both to and from) a selected method property or a constructor. The call hierarchy also shows the implementation of interface and the overrides of virtual or abstract methods. This window is very helpful in understanding the code flow, and evaluating the effect of making changes. The best part is it is available at design time and not at runtime only like a debugger.

    7)      Highlighting references – One of the very cool stuff in Visual Studio 2010 is the fact if you select a variable then all the use of that variable will be highlighted alongside. This should work for all the result of symbols returned by Find all reference. This also works for Name of class, objects variable, properties and methods. We can also use the Ctrl + Shift + Down Arrow or Up Arror to move through them.

    8)      Generate from usage - The Generate from usage feature lets you use classes and members before you define them. You can generate a stub for any undefined class, constructor, method, property, field, or enum that you want to use but have not yet defined. You can generate new types and members without leaving your current location in code, This minimizes interruption to your workflow.

    9)      IntelliSense Suggestion Mode - IntelliSense now provides two alternatives for IntelliSense statement completion, completion mode and suggestion mode. Use suggestion mode for situations where classes and members are used before they are defined. In suggestion mode, when you type in the editor and then commit the entry, the text you typed is inserted into the code. When you commit an entry in completion mode, the editor shows the entry that is highlighted on the members list. When an IntelliSense window is open, you can press CTRL+ALT+SPACEBAR to toggle between completion mode and suggestion mode.

    10)   Application Lifecycle Management – A client application for management of application lifecycle like version control, work item tracking, build automation, team portal etc is available for free (this is not available for express edition.).

    11)   Start Page – The start page has been redesigned with WPF for new functionality and look. Tabbed areas are provided for content from different source including MSDN. Once you open some project the start page closes automatically. The list of recent project also lets you remove project from the list. And above all the start page is customizable enough to be changed as per individual requirement.

    12)   Extension Manager – Visual Studio 2010 has provided good ways to be extended. We can also use MEF to extend most of the features of Visual Studio. The new extension manager now can go the visual studio gallery and install the extension without even opening any explorer.

    13)   Code snippets – Visual studio 2010 for HTML, Jscript and Asp.net also.

    14)   Improved Intelligence for JavaScript has been improved vastly (around 2-5 times). Intelligence now also shows the XML documentation comment on the go.

    15)   Web Deployment – Web Deployment has been vastly improved. We can package and publish the web application in one click. Three major supported deployment scenarios are Web packages, one click deployment and Web configuration Transformation.

    16)   SharePoint - Visual Studio 2010 also brings vastly improved development experience for SharePoint. We can create, edit, debug, package, deploy and activate SharePoint project from within Visual Studio. Deployment of Site is as easy as hitting F5.

    17)   Azure – Visual Studio 2010 also comes with handy improvement for developing on windows Azure environment.

    Vikram

  • LINQ and the use of Repeat and Range operator

    LINQ is also very useful when it comes to generation of range or repetition of data.  We can generate a range of data with the help of the range method.

        var numbers =

            from n in Enumerable.Range(100, 50)

            select new {Number = n, OddEven = n % 2 == 1 ? "odd" : "even"};


    The above query will generate 50 records where the record will start from 100 till 149. The query also determines if the number is odd or even.

    But if we want to generate the same number for multiple times then we can use the Repeat method.

        var numbers = Enumerable.Repeat(7, 10);


    The above query will produce a list with 10 items having the value 7.

    Vikram


  • Retrieving only the first record or record at a certain index in LINQ

    While working with data it’s not always required that we fetch all the records. Many a times we only need to fetch the first record, or some records in some index, in the record set. With LINQ we can get the desired record very easily with the help of the provided element operators.

    Simple get the first record.

    If you want only the first record in record set we can use the first method [Note that this can also be done easily done with the help of the take method by providing the value as one].

        List<Product> products = GetProductList();

     

        Product product12 = (

            from prod in products

            where prod.ProductID == 12

            select prod)

            .First();

     

    We can also very easily put some condition on which first record to be fetched.

        string[] strings = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };

        string startsWithO = strings.First(s => s[0] == 'o');

     

    In the above example the result would be “one” because that is the first record starting with “o”.

     

    Also the fact that there will be chances that there are no value returned in the result set. When we know such possibilities we can use the FirstorDefault() method to return the first record or incase there are no records get the default value.   


        int[] numbers = {};

        int firstNumOrDefault = numbers.FirstOrDefault();

     

    In case we do not want the first record but the second or the third or any other later record then we can use the ElementAt() method. In the ElementAt() method we need to pass the index number for which we want the record and we will receive the result for that element. 


        int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

     

        int fourthLowNum = (

            from num in numbers

            where num > 5

            select num )

            .ElementAt(1);

    Vikram

  • LINQ and conversion operators

    LINQ has a habit of returning things as IEnumerable. But we have all been working with so many other format of lists like array ilist, dictionary etc that most of the time after having the result set we want to get them converted to one of our known format. For this reason LINQ has come up with helper method which can convert the result set in the desired format. Below is an example

    var sortedDoubles =

            from d in doubles

            orderby d descending

            select d;

        var doublesArray = sortedDoubles.ToArray();

    This way we can also transfer the data to IList and Dictionary objects.

    Let’s say we have an array of Objects. The array contains all different types of data like double, int, null, string etc and we want only one type of data back then also we can use the helper function ofType. Below is an example

        object[] numbers = { null, 1.0, "two", 3, "four", 5, "six", 7.0 };

        var doubles = numbers.OfType<double>();

    Vikram

  • Using set operation in LINQ

    There are many set operation that are required to be performed while working with any kind of data. This can be done very easily with the help of LINQ methods available for this functionality. Below are some of the examples of the set operation with LINQ.

    Finding distinct values in the set of data.

    We can use the distinct method to find out distinct values in a given list.

        int[] factorsOf300 = { 2, 2, 3, 5, 5 };

        var uniqueFactors = factorsOf300.Distinct();

    We can also use the set operation of UNION with the help of UNION method in the LINQ. The Union method takes another collection as a parameter and returns the distinct union values in  both the list. Below is an example.

        int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 };
        int[] numbersB = { 1, 3, 5, 7, 8 };
        var uniqueNumbers = numbersA.Union(numbersB);

    We can also get the set operation of INTERSECT with the help of the INTERSECT method. Below is an example.

        int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 };

        int[] numbersB = { 1, 3, 5, 7, 8 };

       

        var commonNumbers = numbersA.Intersect(numbersB);

     

    We can also find the difference between the 2 sets of data with the help of except method.

     

        int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 };

        int[] numbersB = { 1, 3, 5, 7, 8 };

       

        IEnumerable<int> aOnlyNumbers = numbersA.Except(numbersB);

     

    Vikram

  • Grouping data in LINQ with the help of group keyword

    While working with any kind of advanced query grouping is a very important factor. Grouping helps in executing special function like sum, max average etc to be performed on certain groups of data inside the date result set. Grouping is done with the help of the Group method. Below is an example of the basic group functionality.

        int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

       

        var numberGroups =

            from num in numbers

            group num by num % 5 into numGroup

            select new { Remainder = numGroup.Key, Numbers = numGroup };

     

    In the above example we have grouped the values based on the reminder left over when divided by 5. First we are grouping the values based on the reminder when divided by 5 into the numgroup variable.  numGroup.Key gives the value of the key on which the grouping has been applied. And the numGroup itself contains all the records that are contained in that group.

    Below is another example to explain the same.

    string[] words = { "blueberry", "abacus", "banana", "apple", "cheese" };

       

        var wordGroups =

            from num in words

            group num by num[0] into grp

            select new { FirstLetter = grp.Key, Words = grp };


    In the above example we are grouping the value with the first character of the string (num[0]).

    Just like the order operator the group by clause also allows us to write our own logic for the Equal comparison (That means we can group Item by ignoring case also by writing out own implementation). For this we need to pass an object that implements the IEqualityComparer<string> interface. Below is an example.

    public class AnagramEqualityComparer : IEqualityComparer<string>

    {

        public bool Equals(string x, string y) {

            return getCanonicalString(x) == getCanonicalString(y);

        }

     

        public int GetHashCode(string obj) {

            return getCanonicalString(obj).GetHashCode();

        }

       

        private string getCanonicalString(string word) {

            char[] wordChars = word.ToCharArray();

            Array.Sort<char>(wordChars);

            return new string(wordChars);

        }

    }

     

    string[] anagrams = {"from   ", " salt", " earn", "  last   ", " near "};

    var orderGroups = anagrams.GroupBy(w => w.Trim(), new AnagramEqualityComparer());

    Vikram

     

  • LINQ and ordering of the result set

    After filtering and retrieving the records most of the time (if not always) we have to sort the record in certain order. The sort order is very important for displaying records or major calculations. In LINQ for sorting data the order keyword is used.

    With the help of the order keyword we can decide on the ordering of the result set that is retrieved after the query.  Below is an simple example of the order keyword in LINQ.

        string[] words = { "cherry", "apple", "blueberry" };

        var sortedWords =

            from word in words

            orderby word

            select word;

    Here we are ordering the data retrieved based on the string ordering. If required the order can also be made on any of the property of the individual like the length of the string.

        var sortedWords =

            from word in words

            orderby word.Length

            select word;

    You can also make the order descending or ascending by adding the keyword after the parameter.

        var sortedWords =

            from word in words

            orderby word descending

            select word;

    But the best part of the order clause is that instead of just passing a field you can also pass the order clause an instance of any class that implements IComparer interface. The IComparer interface holds a method Compare that Has to be implemented. In that method we can write any logic whatsoever for the comparision. In the below example we are making a string comparison by ignoring the case.

    string[] words = { "aPPLE", "AbAcUs", "bRaNcH", "BlUeBeRrY", "cHeRry"};

    var sortedWords = words.OrderBy(a => a, new CaseInsensitiveComparer());

     

    public class CaseInsensitiveComparer : IComparer<string>

    {

        public int Compare(string x, string y)

        {

            return string.Compare(x, y, StringComparison.OrdinalIgnoreCase);

        }

    }

     

    But while sorting the data many a times we want to provide more than one sort so that data is sorted based on more than one condition. This can be achieved by proving the next order followed by a comma.

        var sortedWords =

            from word in words

            orderby word , word.length

            select word;

    We can also use the reverse() method to reverse the full order of the result set.

        var sortedWords =

            from word in words

            select word.Reverse();                                

    Vikram

  • Using Take and skip keyword to filter records in LINQ

    In LINQ we can use the take keyword to filter out the number of records that we want to retrieve from the query. Let’s say we want to retrieve only the first 5 records for the list or array then we can use the following query

        int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

        var first3Numbers = numbers.Take(3);

    The TAKE keyword can also be easily applied to list of object in the following way.

    var first3WAOrders = (

            from cust in customers

            from order in cust.Orders

            select cust ) .Take(3);

    [Note in the query above we are using the order clause so that the data is first ordered based on the orders field and then the first 3 records are taken.

    In both the above example we have been able to filter out data based on the number of records we want to fetch. But in both the cases we were fetching the records from the very beginning. But there can be some requirements whereby we want to fetch the records after skipping some of the records like in paging.

    For this purpose LINQ has provided us with the skip method which skips the number of records passed as parameter in the result set.

    int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

    var allButFirst4Numbers = numbers.Skip(4);

    The SKIP keyword can also be easily applied to list of object in the following way.

    var first3WAOrders = (

            from cust in customers

            from order in cust.Orders

            select cust ).Skip(3);

     

    Vikram