Pranay Rana: LINQ
Showing posts with label LINQ. Show all posts
Showing posts with label LINQ. Show all posts

Tuesday, April 12, 2016

Diffence between list of user defined types

Below is discussion about finding out difference between two lists of elements.

Easiest way to find out difference between two list is make use of method Except, which is introduced with Linq feature in .Net framework 3.5.

Except method works as below



So when except method is applied on two List A and List B, it get list of all element which are present in list A only.

Let’s understand same by writing Code

List<int> a = new List<int>() { 2, 4, 7, 9, 4 };
List<int> b = new List<int>() { 8, 6, 7, 3, 4 };

var lst = a.Except(b);
foreach (var ele in lst)
{
    Console.WriteLine(ele);
}
Above code defines two list of integer, and apply Except method to find difference between them.

Output 
 


Output prints 2 & 9, which are the element in “List a” and not in “List b”. If one want to find out element which are present in “List b” and not in “List a”, than code will be like

var lst = b.Except(a);//pint output 8,6 & 3

Note:
Except method returns element of the collection which is on left side, it doesn’t get list of those element of the right side collection element which is not part of left side collection.

Except on User Defined typed List
Below is explain about how Except works when applied on user-defined data type, to understand this let’s defined employee class

public class Employee
{
    public int ID { get; set; }
    public string Name { get; set; }
}

After defining Employee class below code creates two list of Employee and applies Except method on it

List<Employee> lstA = new List<Employee>() { new Employee { ID = 1, Name = "Abc" }, 
                         new Employee { ID = 2, Name = "Pranay" },
                         new Employee { ID = 3, Name = "Hemang" }};
 List<Employee> lstB = new List<Employee>() { new Employee { ID = 4, Name = "Xyz" }, 
                         new Employee { ID = 2, Name = "Pranay" },
                         new Employee { ID = 5, Name = "Virendra" }};

var lst = lstB.Except(lstA);
foreach (var ele in lst)
{
     Console.WriteLine(ele.ID + " " + ele.Name);
}

Output 
 


So output print out all the element of list B, rather than printing elements which are not present in list A.
Problem here is when Except method applied on user-defined datatype it tries to compare references of object to find difference between lists.

Resolution
To resolve problem, there is need to use Except overload method which takes list as first input and Custom Equality Comparer as its second parameter for type. Custom Equality comparer helps to do comparison between object of list and returns difference between list.

public class EmployeeComparer : IEqualityComparer<Employee>
{
     bool IEqualityComparer<Employee>.Equals(Employee x, Employee y)
     {
        if (x == null || y == null)
            return false;

        return x.ID == y.ID;
     }

    int IEqualityComparer<Employee>.GetHashCode(Employee obj)
    {
       if (obj == null)
           return 0;

       return obj.ID.GetHashCode();
    }
}
Above code defines Custom Employee comparer which implements IEqualityComparer and does comparison of employee objects based on ID property defined in employee class.

Now when Except method applied on list as in below code,

List<Employee> lstA = new List<Employee>() { new Employee { ID = 1, Name = "Abc" }, 
                         new Employee { ID = 2, Name = "Pranay" },
                         new Employee { ID = 3, Name = "Hemang" }};

List<Employee> lstB = new List<Employee>() { new Employee { ID = 4, Name = "Xyz" }, 
                         new Employee { ID = 2, Name = "Pranay" },
                         new Employee { ID = 5, Name = "Virendra" }};

var lst = lstB.Except(lstA, new EmployeeComparer());
foreach (var ele in lst)
{
     Console.WriteLine(ele.ID + " " + ele.Name);
}
Output 
 


Output prints element of list B which are not present in List A of employee. So comparer makes it easy to find difference between two lists.

Thursday, March 14, 2013

Object to XML using LINQ or XmlSerializer

In Following post I am going show you how easily you can convert you object in the XML string, because sometime there is need of pass object and XML from one function to another and also convert XML string back to object. But As title suggest here I just going to discuss the conversion of object to XML string.

Following two way to achieve this task of converting Object to XML.

Before we start Below is class structure which object need to be convert in XML string.
public class Product
    {
        public string Name { get; set; }
        public int Code { get; set; }
        public List<productType> types {get; set;}
    }

    public class productType
    {
        public string type {get; set;}
    }
As you can see in structure Product is class and it's having list of producttype in it.

Way 1 : Linq To XML
 List<productType> typ = new List<productType>();
            typ.Add((new productType() { type="Type1"}));
            typ.Add((new productType() { type = "Type2" }));
            typ.Add((new productType() { type = "Type3" }));

            Product[] products = { new Product { Name = "apple", Code = 9,types=typ }, 
                       new Product { Name = "orange", Code = 4,types=typ   }, 
                       new Product { Name = "apple", Code = 9 ,types=typ}, 
                       new Product { Name = "lemon", Code = 9,types=typ } };
Above code is creating array of product which contains the object of product. Over all its initializing the product array object.Now to convert this in the XML using Linq following is code
            XElement _customers = new XElement("Products",
                       from c in products
                       orderby c.Code 
                        select new XElement("product",
                            new XElement("Code", c.Code),
                            new XElement("Name", c.Name),
                            new XElement("Types", (from x in c.types
                                                  orderby x.type//descending 
                            select new XElement("Type",x.type)) 
                        ))
                  );

            Console.WriteLine(_customers.ToString());
As you see in above code its converting the each property of object in XMLElement by using method of Linq To XML which is XElement. You can modify structure as per you needs here is more on Linq to XML

Output



Way 2 : Make use of XmlSerializer
You can easily convert the object in XML string by using Serializer as shown below. This process called as object serialization.
            XmlSerializer xser = new XmlSerializer(products.GetType());
            xser.Serialize(Console.Out, products);
            Console.ReadLine();
As you see there just two line of code need to conversion. There is no need to write more amount of the code like Linq To XML, But if you want to control structure of the generated XML you need to decorate your class with XmlAttributes. Read more about this XmlSerializer

Output



Comparison between both the ways
  • Big difference between both is way XML string is generated. That you can easily figure out form the Output of both the way.
  • XmlSerializer provide more control on XML than than the Lin To XML.
  • As stated with Linq to Xml you need to write down more amount of code to structure the XML string which is very easy with XmlSerializer. But if you dont want the default structure generated by XmlSerializer you need to use XmlAttributes for each property. with attribute class will be

 public class Product
    {
        [XmlElement("Product Name")]
        public string Name { get; set; }
        [XmlElement("Code")]
        public int Code { get; set; }
        [XmlElement("Types")]
        public List types {get; set;}
    }
But you can easily do this in Linq to XML.
  •  When you dont want to include some property in XML string. you just need to skip that property like this.
XElement _customers = new XElement("Products",
                       from c in products
                       orderby c.Code //descending 
                        select new XElement("product",
                            //new XElement("Code", c.Code),
                            new XElement("Name", c.Name),
                            new XElement("Types", (from x in c.types
                                                  orderby x.type//descending 
                            select new XElement("Type",x.type)) 
                        ))
                  );
in linq to xml you just need to remove it here i just commented Code so there is no element for Code.






For XmlSerializer you need to put attribute called [Obsolete] on top of property.
        public string Name { get; set; }
        [Obsolete]
        public int Code { get; set; }
        public List types {get; set;}

  • Another Difference is Linq TO XML is faster than XmlSerializer which you can easy see by running the code its because XmlSerializer is Serializing object which might be using reflection and other metadata information about the object.
Conclusion
You can use one of the way as per your need. But if you just want to generate XML than its better to go for Linq to XML and if there is serialization/ de-serialization required than go for XmlSerializer .

Provide comments if you find more difference and there is thing change require in above. Thanks for reading.

Friday, January 25, 2013

DistinctBy in Linq (Find Distinct object by Property)

In this post I am going to discuss about how to get distinct object using property of it from collection. Here I am going to show three different way to achieve it easily.
In this post I am going to discuss about extension method that can do task more than the current Distinct method available in .Net framework.

Distinct method of Linq works as following right now.
public class Product
{
    public string Name { get; set; }
    public int Code { get; set; }
}
Consider that we have product Class which is having Code and Name as property in it.
Now Requirement is I have to find out the all product with distinct Code values.
Product[] products = { new Product { Name = "apple", Code = 9 }, 
                       new Product { Name = "orange", Code = 4 }, 
                       new Product { Name = "apple", Code = 10 }, 
                       new Product { Name = "lemon", Code = 9 } };
var lstDistProduct = products.Distinct();
foreach (Product p in list1)
{
     Console.WriteLine(p.Code + " : " + p.Name);
}
Output

It returns all the product event though two product have same Code value. So this doesn't meet requirement of getting object with distinct Code value.

Way 1 : Make use of MoreLinq Library
First way to achieve the requirement is make use of MoreLinq Library, which support function called DistinctBy in which you can specify the property on which you want to find Distinct objects.
Below code is shows the use of the function.
var list1 = products.DistinctBy(x=> x.Code);

foreach (Product p in list1)
{
     Console.WriteLine(p.Code + " : " + p.Name);
}
Output

As  you can see in output there is only two object get return which actually I want. i.e. distinct value by Code or product.
If you want to pass more than on property than you can just do like this  var list1 = products.DistinctBy(a => new { a.Name, a.Code });
You can read about the MoreLinq and Download this DLL from here : http://code.google.com/p/morelinq/ one more thing about this library also contains number of other function that you can check.

Way 2: Implement Comparable
Second way to achieve the same functionality is make use of overload Distinct function which support to have comparator as argument.
here is MSDN documentation on this : Enumerable.Distinct<TSource> Method (IEnumerable<TSource>, IEqualityComparer<TSource>)

So for that I implemented IEqualityComparer and created new ProductComparare which you can see in below code.
   
    class ProductComparare : IEqualityComparer
    {
        private Func<Product, object> _funcDistinct;
        public ProductComparare(Func<Product, object> funcDistinct)
        {
            this._funcDistinct = funcDistinct;
        }

        public bool Equals(Product x, Product y)
        {
            return _funcDistinct(x).Equals(_funcDistinct(y));
        }

        public int GetHashCode(Product obj)
        {
            return this._funcDistinct(obj).GetHashCode();
        }
    }
So In ProductComparare constructor I am passing function as argument, so when I create any object of it I have to pass my project function as argument.
In Equal method I am comparing object which are returned by my projection function.
Now following is the way how I used this Comparare implementation to satisfy my requirement.
var list2 = products.Distinct(new ProductComparare( a => a.Code ));

            foreach (Product p in list2)
            {
                Console.WriteLine(p.Code + " : " + p.Name);
            }
Output

So this approach also satisfy my requirement easily. I not looked in code of MoreLinq library but I think its also doing like this only. If you want to pass more than on property than you can just do like this  var list1 = products.Distinct(a => new { a.Name, a.Code });.

Way 3: Easy GroupBy wa
The third and most eaisest way to avoide this I did in above like using MoreLine and Comparare implementation is just make use of GroupBy like as below
 List<Product> list = products
                   .GroupBy(a => a.Code )
                   .Select(g => g.First())
                   .ToList();

            foreach (Product p in list)
            {
                Console.WriteLine(p.Code + " : " + p.Name);
            }
In above code I am doing grouping object on basis of property and than in Select function just selecting fist one of the each group will doing work for me.
Output

So this approach also satisfy my requirement easily and output is similar to above two approach. If you want to pass more than on property than you can just do like this   .GroupBy(a => new { a.Name, a.Code }).

So this one is very easy trick to achieve the functionality that I want without using any thing extra in my code.

Conclusion
So Above is the way you can achieve Distinct of collection easily by property of object.

Leave comment if you have any query or if you like it.

Tuesday, January 22, 2013

Index of Collection Using Linq

This is small post regarding How to get the index of each element in collection. There are sometime requirement to bind list of element with the dropdwon or list control with index as value and Data as Text value in this case you need to get index for each element.

Following is piece of code that make use of Linq and get the indexes for each element in collection.

//example of getting index of List Element
List<string> ListItems = 
       new List<string> { "Test1", "Test2", "Test3", "Test4" };
var ListWithIndex= someItems.Select((item, index) => new
{
      ItemName = item,
      Position = index
});

//example of getting index of Array Element
string[] ArryItem= { "Item1", "Item2", "Item3", "Item4" };
var ArraywithInex= someItems.Select((item, index) => new
{
      ItemName = item,
      Position = index
});
As you see in code there is one lambda function passed in the Select function of linq, and another point to note down is each elemtn has index associated with it. So by applying function like above in linq its easy to get the index of element.

Monday, December 31, 2012

Tuple Type in C#4.0

What is Tuple type ?
Tuple is new class type added in C#4.0. Tuple type allows to create data structure which is consist of specific type and specific number of elements. In the following post its about basic of Tuple type, how and where to use this new type in your code.

How to create Tuple type object
Following code show how you can create and use this class type.
Console.WriteLine("How to create and use");
Tuple<int, string> tuple = new Tuple<int, string>(1, "pranay");
Console.WriteLine(tuple.Item1 + "-" + tuple.Item2);
One way to create object is just make use of constructor and create the Tuple object.
Tuple<int, string> tuple1 = Tuple.Create(2, "ab1");
Console.WriteLine(tuple1.Item1 + "-" + tuple1.Item2);
Console.WriteLine();
Second way is make use of Create Static method supported by Tuple class and create object.

Refer Element of Tuple Object
As you see in both example element of Tuple get referred using name Item1 and Item2, so this is predefined name for the element by .net framework only. So to refer element in Tuple object you need to write "Item+number_of_the_element".

Constrain
You cannot change value of the the property of Tuple object.
// after creation of object this is not possible
// this gives compile time error
tuple1.Item1 = 100; 

C# allows to create Tuple object with the 7 different type element.
Create<T1>(T1) Creates a new 1-tuple, or singleton.
Create<T1, T2>(T1, T2) Creates a new 2-tuple, or pair.
Create<T1, T2, T3>(T1, T2, T3) Creates a new 3-tuple, or triple.
Create<T1, T2, T3, T4>(T1, T2, T3, T4) Creates a new 4-tuple, or quadruple.
Create<T1, T2, T3, T4, T5>(T1, T2, T3, T4, T5) Creates a new 5-tuple, or quintuple.
Create<T1, T2, T3, T4, T5, T6>(T1, T2, T3, T4, T5, T6) Creates a new 6-tuple, or sextuple.
Create<T1, T2, T3, T4, T5, T6, T7>(T1, T2, T3, T4, T5, T6, T7) Creates a new 7-tuple, or septuple.

What to do if you want to have more than 8 values ?
Last variation of Tuple creation allows to create Tuple object with more than 8 different element.
Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1, T2, T3, T4, T5, T6, T7, T8) Creates a new 8-tuple, or octuple. 
in this T8 element is of type Tuple only that means if you want to create tuple more than 8 it will be like this
var num = new Tuple<int, int, int, int, int, int, int, 
                 Tuple<int>>(1, 2, 3, 4, 5, 6, 7, 
                 new Tuple<int>(8));

Use Of Tuple type
To Pass data To methods
Sometime we just create class or structure to just pass data to method, creation of this extra class or structure in code can be avoided by using Tuple object to pass data.
Following is example of this where object of Tuple used to pass int and string data. And its shows that we can also create list of Tuple object and pass to method for processing.
ProcessData(new Tuple<int, string>(1, "Pranay"));

List<Tuple<int, String>> lst = new List<Tuple<int, string>>();
lst.Add(new Tuple<int, string>(1, "Pranay"));
lst.Add(Tuple.Create(2, "ab1"));
lst.Add(Tuple.Create(1, "abcdef"));
lst.Add(Tuple.Create(3, "cd2"));
ProcessListOfData(lst);

//Process single Tuple object
public static void ProcessData(Tuple<int, string> tup)
{
    Console.WriteLine("ProcessData");
    Console.WriteLine(tup.Item1 + "-" + tup.Item2);
    Console.WriteLine();
}
//Process list of Tuple object
public static void ProcessListOfData(List<Tuple<int, String>> lst)
{
    Console.WriteLine("ProcessListOfData");
    var data = lst.Where(x => x.Item1 == 1).Select(x => x);
    foreach (var tup in data)
    {
       Console.WriteLine(tup.Item1 + "-" + tup.Item2);
    }
    Console.WriteLine();
}

To Return From the Method 
Tuple can be used to return data from method where you want to return more than one value or list of object without creating extra class or structure for carrying data.
Following is example of returning data type.
var data = ReturnTupleData();
Console.WriteLine(data.Item1 + "-" + data.Item2);

public static Tuple<int, string> ReturnTupleData()
{
    return new Tuple<int, string>(1, "pranay");
}
As you can see it use Tuple object to return int and string data which is not possible with the normal method because we only have one return type.

To Return Anonymous Type 
Following is example of using Tuple with linq where most of the time we return anonymous type from the method because we just have to select only require number of property from set of property object have.
foreach (var tup in ProcessListOfDataAndReturn(lst))
{
     Console.WriteLine(tup.Item1 + "-" + tup.Item2+"-" + tup.Item3);
}
Console.WriteLine();

public static IEnumerable<Tuple<int, string, int>> ProcessListOfDataAndReturn(List<Tuple<int, String>> lst)
{
     Console.WriteLine("ProcessListOfDataAndReturn");
     var data = from tup in lst
                select new Tuple<int, string, int>
                    (
                        tup.Item1,
                        tup.Item2,
                        tup.Item2.Length
                     );
     return data.ToList();
}
You cannot return anonymous type from the method which is one of the constrain. There are other ways to return it from the method which is already discuss by me here Return Anonymous type.
But with the help of Tuple we can easily return Anonymous type data which you can see in above code.

Conclusion
This inbuilt Tuple class in C#4.0 can be use to avoid issue discuss above and also to simplify code at some point

Full Source code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TupleTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("How to crate and use");
            Tuple<int, string> tuple = new Tuple<int, string>(1, "pranay");
            Tuple<int, string> tuple1 = Tuple.Create(2, "ab1");
            Console.WriteLine(tuple.Item1 + "-" + tuple.Item2);
            Console.WriteLine(tuple1.Item1 + "-" + tuple1.Item2);
            Console.WriteLine();
         
            ProcessData(new Tuple<int, string>(1, "Pranay"));

            List<Tuple<int, String>> lst = new List<Tuple<int, string>>();
            lst.Add(new Tuple<int, string>(1, "Pranay"));
            lst.Add(Tuple.Create(2, "ab1"));
            lst.Add(Tuple.Create(1, "abcdef"));
            lst.Add(Tuple.Create(3, "cd2"));
            ProcessListOfData(lst);

            Console.WriteLine("ReturnTupleData");
            var data = ReturnTupleData();
            Console.WriteLine(data.Item1 + "-" + data.Item2);
            Console.WriteLine();

            foreach (var tup in ProcessListOfDataAndReturn(lst))
            {
                Console.WriteLine(tup.Item1 + "-" + tup.Item2+"-" + tup.Item3);
            }
            Console.WriteLine();

            Console.ReadLine();
        }

        public static void ProcessData(Tuple<int, string> tup)
        {
            Console.WriteLine("ProcessData");
            Console.WriteLine(tup.Item1 + "-" + tup.Item2);
            Console.WriteLine();
        }


        public static void ProcessListOfData(List<Tuple<int, String>> lst)
        {
            Console.WriteLine("ProcessListOfData");
            var data = lst.Where(x => x.Item1 == 1).Select(x => x);
            foreach (var tup in data)
            {
                Console.WriteLine(tup.Item1 + "-" + tup.Item2);
            }
            Console.WriteLine();
        }

        public static Tuple<int, string> ReturnTupleData()
        {
            return new Tuple<int, string>(1, "pranay");
        }

        public static IEnumerable<Tuple<int, string, int>> ProcessListOfDataAndReturn(List<Tuple<int, String>> lst)
        {
            Console.WriteLine("ProcessListOfDataAndReturn");
            var data = from tup in lst
                       select new Tuple<int, string, int>
                       (
                           tup.Item1,
                           tup.Item2,
                           tup.Item2.Length
                       );
            return data.ToList();
        }
    }
}

Leave comment if you have any query or if you like it.

Monday, November 26, 2012

Linq Query to compare only Date part of DateTime

In this post I am going to discuss about comparing the date part of the datetime in linq query. In linq query its easy to perform datetime comparison how to compare only date not time part of datetime filed of your entity.

Let have coloseure look, In Sql Server one can do something like as below to just compare date part of the field.
SELECT * FROM dbo.tbl_MyTable
WHERE 
CAST(CONVERT(CHAR(10), DateTimeValueColumn, 102) AS DATE) = 
            CAST(CONVERT(CHAR(10),GETDATE(),102) AS DATE)
So in above query convert function did task of removing time part and only date part comparison happens.

Linq Queires
Following discussion about doing same task using linq queries.
Solution 1:
First way to achieve same thing (i.e. comparing date part) of entity or object is following

var data = context.t_quoted_value.Where(x => x.region_name == "Hong Kong" 
                  && DateTime.Compare(x.price_date.Value.Date, dt.Date) == 0)
                  .ToList();

Here Date property of DatTime used to get only date part of datetime property and made use of DateTime.Compare function to get matching object.

But the problem with this approach when make use of EnityFramework i.e. Linq To Entity , its gives following error at runtime

The specified type member 'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.

so to avoid above error in Linq to Entity query is modified to following

var data = context.t_quoted_value.Where(x => x.region_name == "Hong Kong")
                            .ToList()
                            .Where (x=> DateTime.Compare(x.price_date.Value.Date, dt.Date) == 0)
                            .ToList(); 

So in above query first data is get fetched from the database and than on list date comparison get applied. But the problem with this approach is need to load all data first than the date comparison get applied because entityframework doesn't support direct query.

Solution 2:
One more easy and simple solution to just compare datet part of datetime object is as following
            
var data1 = context.t_quoted_value.Where(x => x.region_name == "Hong Kong" 
                            && x.price_date.Value.Year == dt.Year
                            && x.price_date.Value.Month == dt.Month
                            && x.price_date.Value.Day == dt.Day).ToList();
its query use the year,month and day property of datetime object to compare date. Advantage of this solution is this is compatible with all flavor of Linq i.e. it works in linq to sql, linq to object and also in linq to enitity.

Conclusion
So the post is useful when you need to compare only date part of datetime property in Linq queries.

Leave your comments if you like it.

Wednesday, November 7, 2012

Read Xml with Descendants Method (XName)

This post is about understanding Descendants and avoid misconception with this method.
Recently I read one question on StackOverFlow  about reading xml using Linq To Xml to get node values. In that developer made use of Descendants Method to get the child node values.

Let see the actual problem here following is XML to read. And developer wrote code to read out value of orderid node.
<ordersreport date="2012-08-01">
<returns>
      <amount>
        <orderid>2</orderid>
        <orderid>3</orderid>
        <orderid>21</orderid>
        <orderid>23</orderid>
      </amount>
    </returns>
</ordersreport>
So code written like this
    var amount = documentRoot.Descendants("Amount")
               .Select(y => new
               {
                  OrderId = (int)y.Element("OrderId")
               });
               foreach (var r in amount)
               {
                  Console.WriteLine(r.OrderId);
               }
Ouput of above code is
 2
that is only first orderid element value which is child of Amount , So misconception here by developer of the code is Descendants("Amount") returns child element of the Amount tag i.e. all orderId element.

Now to Understand Descendants function in better way I visited to MSDN link which says something like this
XContainer.Descendants Method (XName) - Returns a filtered collection of the descendant elements for this document or element, in document order. Only elements that have a matching XName are included in the collection. So as per the defincation on MSDN problem with code
    var amount = doc.Descendants("Amount")                         
      .Select(y => new
      {
       OrderId = (int)y.Element("OrderId")
       });
will give you Element Amount and when you write y.Element("OrderId") will return you fist element of its child.
Descendants - doesn't mean than its return the child element of element name rather than method look for descendants of element or if name of elemnt specified as parameter than matching descendants.
Finally I got following solution to get it properly work
XElement documentRoot  = 
     XElement.Parse (@"<ordersreport date="2012-08-01">
                             <returns>
                              <amount>
                                  <orderid>2</orderid>                                                    
                                  <orderid>3</orderid>
                                  <orderid>21</orderid>
                                  <orderid>23</orderid>
                               </amount>
                             </returns>
                        </ordersreport>");
Solution 1
var orderids = from order in
                  documentRoot.Descendants("Amount").Descendants()
                  select new
                  {
                     OrderId = order.Value
                  };
As per the information on MSDN documentRoot.Descendants("Amount").Descendants() give list of orderId elements.

Solution 2
var orderids = from order in
                    documentRoot.Descendants("OrderId")
                    select new
                    {
                       OrderId = order.Value
                    };
or the second solution is just bit easy than this just make use of documentRoot.Descendants("OrderId") that will give all orderidelement.

Conclusion
This post is just for avoiding misconception related to Descendants and understand it properly.

Leave your comments if you like it.

Tuesday, October 9, 2012

Return Anonymous type

In this post I am going to discuss about returning the anonymous type and how to handle in code. Following is list of fact about anonymous type.  

Quick facts about Anonymous type
  • Anonymous types are reference type derived form system.objects.
  • Properties of the Anonymous type is read only.
  • If two Anonymous type has same properties and same order than compiler treats its as same type. But if both are in one assembly.
  • Anonymous type has method scope. If you want to return Anonymous type form the method than you have to convert it in object type. But is not good practice.
You can read more on blog about this: Anonymous types
As in about facts you cannot return anonymous type from the method , if you want to return you need to cast it in object.
Now in following post I am going to do same return the anonymous type as object and going to show three different way to handle it.
  • Way 1: Handle using Dynamic type 
  • Way 2: Handle by creating same anonymous type 
  • Way 3: Handle using Reflection
To Understand each way I created following method which returns anonymous type
object AnonymousReturn()
{
     return new { Name = "Pranay", EmailID = "pranayamr@gmail.com" }; 
}
Way 1: Handle using Dynamic type
dynamic newtype= AnonymousReturn();
Console.WriteLine(newtype.Name + "  " + newtype.EmailID);
As you see in above example first line of code calling method which is returning anonymous type as object and assign the return value to dynamic type. Second line of code just printing the property value of anonymous type.
Note : No intelligence support as we are using dynamic type. And need to remember the property name and type also.

Way 2: Handle by creating same anonymous type
object o = AnonymousReturn();
var obj = Cast(o, new { Name = "", EmailID = "" });
Console.WriteLine(obj.Name + "  " + obj.EmailID);
In this way return value of the anonymous type is get assigned to object. Next line of the code cast object to the same anonymous type. To accomplish this task following method does casting of object.
T Cast<T>(object obj, T type) { return (T)obj; }
This done song type conversation and provide intelligence support.

Way 3: Handle using Reflection
object refobj = AnonymousReturn();
Type type = refobj.GetType(); 
PropertyInfo[] fields = type.GetProperties(); 
foreach (var field in fields) 
{
   string name = field.Name; 
   var temp = field.GetValue(obj, null);
   Console.WriteLine(name + "  " + temp);
}
This way making use of reflection feature of .net. First line of code call the method and assign return value to refobj. Second line of code get the Type of the object and than following line of code get the property of anonymous type and print value of it.
Check out full Source code of to test all technique we discuss
using System;p
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            dynamic newtype= p.AnonymousReturn();
            Console.WriteLine("With Dynamic Type");
            Console.WriteLine(newtype.Name + "  " + newtype.EmailID);
            Console.WriteLine();
            Console.WriteLine("With Creation of same anonymous type");
            object o = p.AnonymousReturn();
            var obj = p.Cast(o, new { Name = "", EmailID = "" });
            Console.WriteLine(obj.Name + "  " + obj.EmailID);
            Console.WriteLine();
            Console.WriteLine("With Reflection");
            object refobj = p.AnonymousReturn();
            Type type = refobj.GetType(); 
            PropertyInfo[] fields = type.GetProperties(); 
            foreach (var field in fields) 
            {
                string name = field.Name; 
                var temp = field.GetValue(obj, null);
                Console.WriteLine(name + "  " + temp);
            }

            Console.ReadLine();
        }

         object AnonymousReturn()
        {
            return new { Name = "Pranay", EmailID = "pranayamr@gmail.com" }; 
        }

        T Cast<T>(object obj, T type) { return (T)obj; }

        public static void Write()
        {
            Program p = new Program();
            object obj = p.AnonymousReturn();
            
        }
    }
}
Output

Saturday, August 11, 2012

Call Sql Server inbuilt functions using Linq

The post is about the the new class introduce in .net framwork for support of built in SQL-Server function. The SqlFunctions class allows to call SQL-Server function from linq queries while using EntityFramwork.

Following describes how it works
Create Edmx file i.e EntityFramwork file

 Create connection with database

Select Table(s),view(s) and Stored procedure(s)

Created EDMX file

Use SqlFunction in query
Now after deisigning the enityframwork edmx file following is way to utilize the inbuilt sql server functions in Linq queries.
public List<person> SqlTest()
        {
            using (SchoolEntities se = new SchoolEntities())
            {
                var person = from p in se.People
                             where SqlFunctions.CharIndex("a", p.FirstName) == 1
                             select p;
                return person.ToList<person>();
            }
        }
As you see in above linq query its find out all persons whose name starts with letter "a". This is easily achievable by CharIndex function of sql server as you can see in query. This function is part of SqlFunction class avilable in .net framework.

SqlFunction class inside
#region Assembly System.Data.Entity.dll, v4.0.30319
// C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\Profile\Client\System.Data.Entity.dll
#endregion

using System;
using System.Collections.Generic;
using System.Data.Objects.DataClasses;

namespace System.Data.Objects.SqlClient
{
 // Summary:
    //     Provides common language runtime (CLR) methods that call functions in the
    //     database in LINQ to Entities queries.
    public static class SqlFunctions
    {
        ........list of other function that is supported by this class
        //
        // Summary:
        //     Returns the starting position of one expression found within another expression.
        //
        // Parameters:
        //   toSearch:
        //     The string expression to be searched.
        //
        //   target:
        //     The string expression to be found.
        //
        //   startLocation:
        //     The character position in toSearch where searching begins.
        //
        // Returns:
        //     The starting position of target if it is found in toSearch.
        [EdmFunction("SqlServer", "CHARINDEX")]
        public static int? CharIndex(string toSearch, string target, int? startLocation)
    }
}
As you can see SqlFuction is static class and contains static methods which calls sql server inbuilt function.
Get more information about SqlFunction class and its method on msdn at : SqlFunction

Thursday, July 26, 2012

Count() and Count property

In this small post I am going to discuss about the Count property and Count() method that used to return count of number of element in collection.
Count property
Each collection object which is inherited from ICollection<T> Interface has count property which returns number of element in collection.
Count() Function
But the things change when you make use of System.Linq namespace in you code. when you make use of this namespace you get Count() method which also returns you number of element in you collection. But the point to not here is Count() is extestion method of IEnumerable<T> class. Check the following images
Without using Linq namespace

With Using Linq namespace

IEnumerable<T> Source after query

After Converting Source to ICollection<T> type

Code on which I tested
List<string> lst = new List<string>() { "abc", "def" };
int a = lst.Count;
var b = lst.Where(x => x == "abc").Count();
List<string> ls = lst.Where(x => x == "abc").ToList<string>();
a= ls.Count;
If you are using Count() method on source which implements ICollection<T> interface than extension method make use of the Count property of it and returns no of element. If the source not implemented from the ICollection<T> than it do perform the operation on the element of source and return count of it.

Point to Note
- As per MSDN : Retrieving the value of Count property is an O(1) operation.
- Count() function perform the operation and return value, so its slower than count property.

Conclustion
Although its stated that Count() function make use of count property if the source implemented from ICollection<T> than use cont property, its better to use count property directly if source implemented ICollection<T> otherwise go for Count() get number of element in source.

Saturday, May 26, 2012

Get Last n Records using Linq to SQL

The small post is about getting last n number of record(s) from the database table or from the collection using LINQ.

SQL
To get last n number of record(s) from table I do write the following query on my table records in T-SQL.
SELECT TOP n <fields> FROM Forms WHERE <field> = <data> 
ORDER BY <field> DESC
As you see in above query important thing is using order by with desc keyword means reversing the table records - (mostly we apply the order by desc on the primary key of the table).

LINQ
In LINQ we achieve the same thing with the help of OrderByDescending function and Take function.
var qry = db.ObjectCollection
                     .Where(m => m.<field> == data) 
                     .OrderByDescending(m => m.<field>) 
                     .Take(n); 
In above LINQ query same as sql need to apply the where condition first than make collection reverse using order by function and to get top record you just need to make user of Take function.

But to get the last record for the collection you make use of FirstOrDefault function as below
var qry = db.ObjectCollection
                     .Where(m => m.<field> == data) 
                     .OrderByDescending(m => m.<field>) 
                     .FirstOrDefault(); 

Read about the method use on MSDN

Monday, April 16, 2012

Expression Tree

What is Expression Tree ?
Expression is not like other code, but it like binary tree data structure where each node is representing an object children(s). Expression tree is get derived from the Lambda Expression which you can see easily once you can drill down in framework class. One good reason of Expression tree is it allows to create dynamic linq queries.

Expression Class
using System.Collections.ObjectModel;

namespace System.Linq.Expressions
{
    // Summary:
    //     Represents a strongly typed lambda expression as a data structure in the
    //     form of an expression tree. This class cannot be inherited.
    //
    // Type parameters:
    //   TDelegate:
    //     The type of the delegate that the System.Linq.Expressions.Expression
    //     represents.
    public sealed class Expression : LambdaExpression
    {
        // Summary:
        //     Compiles the lambda expression described by the expression tree into executable
        //     code.
        //
        // Returns:
        //     A delegate of type TDelegate that represents the lambda expression described
        //     by the System.Linq.Expressions.Expression.
        public TDelegate Compile();
    }
}
Syntax of Expression
Expression<Func<type,returnType>> = (param) => lamdaexpresion;
NameSpace System.Linq.Expressions; contains defincation of Expression Tree class. so you need to include this namespace before using the Expression in your code.
Example
Expression<Func<int,int, int>> lambda = (a,b) => a *  b;

Expression Tree for the above expression


Install Expression Tree visualizer
If you are not having visualizer to view expression tree than you can install it by following below instruction
Download Samples : http://code.msdn.microsoft.com/csharpsamples
Compile code : Official_Visual_Studio_2008_C#_Samples\ExpressionTreeVisualizer\C#\ExpressionTreeVisualizer\
Get Dll from:
bin\Debug\expressionTreeVisualizer.dll
Install Dll on path : C:\Program Files\Microsoft Visual Studio 9.0\Common7\Packages\Debugger\Visualizers

Expression Tree Parts
Expression tree is consistence of following part, each part is shown in blow images.
Body

Parameters

NodeType and Type Of Expression

Difference Between Lamdab Expression and Expression
In above example I assigned lambda expression to Expression type, by doing that way enviroment represent lambda expression as expression tree not as lambda expression. And if you see memory represtation of expression tee its a object represention of expression which is already seen in expression tree visualizer, which is differnt than lambda epxssion IL.
when you write
Func<int,int, int> lambdaExpression = (a,b) => a *  b;
its a lambda expression.

Important point to Note here is
You cannot use lambda expressions with a statement to create an expression tree
Expression<Func<int, int, bool>> IsAGreater =
    (a, b) => { if (a > b)  return true; else return false; };
above code throw compile time error.

How to Create Expression Tree ?
Fist Way:
First way is very easy that I already sawn is above discussion "Create Lambda expression and assign it to expression."
Expression<Func<int,int, int>> lambda = (a,b) => a *  b;
Something as above.

Second Way:
To create expression you need to follow the below steps one by one. I am also going to show the functions that can be used in dynamic expression.
private void CreateExpressionTree()
 {
Create parameter for the expression.
ParameterExpression exp1 = Expression.Parameter(typeof(int), "a");
        ParameterExpression exp2 = Expression.Parameter(typeof(int), "b");
Create body of the expression, over here in this example using multiply function to get the multiplication of the two parameter.
BinaryExpression exp = Expression.Multiply(exp1,exp2);
        var lamExp = Expression.Lambda<Func<int, int, int>>                     
               (exp, new ParameterExpression[] { exp1, exp2 });
Compile method compile the expression tree and Invoke allows to execute the compiled expression tree. As you see you need to pass the values for the parameter of expression tree.
int c = (lamExp.Compile()).Invoke(2,5); 
        Response.Write(c); 
}

Application of Expression Tree ?
One Application I fond for the Expression tree is to make use of expression to build the dynamic linq query.
Example 1 : - Bind query to get data and sort the data dynamically. As you see in below code I build query and sorting data by passing name of the property in people object. In example Email property used to sort which can be replace by Name property.
private void BindAndSort()
    {
        List<people> people = new List<people>
            {
                new People(){ Name = "Pranay",Email="pranay@test.com",CityID=2 },
                new People(){ Name = "Heamng",Email="Hemang@test.com",CityID=1 },
                new People(){ Name = "Hiral" ,Email="Hiral@test.com",CityID=2},
                new People(){ Name = "Maitri",Email="Maitri@test.com",CityID=1 }
            };

        ParameterExpression param = Expression.Parameter(typeof(People), "People");

        Expression ex = Expression.Property(param, "Email");

        var sort= Expression.Lambda<Func<People, object>>(ex, param); 

        var sortedData =
                        (from s in people
                         select s).OrderBy<people, object>(sort.Compile()).ToList<people>();
        GridViewNotional.DataSource = sortedData;
        GridViewNotional.DataBind();
    }
Example 2 : - Build query to search data from the people entity using Email property and Email starts with "h". Over here property can be replace with the Name property.
ParameterExpression param = Expression.Parameter(typeof(People), "People");
Expression ex = Expression.Property(param, "Email");

// Get the method information for the String.StartsWith() method   
MethodInfo mi = typeof(String).
                GetMethod("StartsWith", new Type[] { typeof(String) });
MethodCallExpression startsWith = 
                Expression.Call(ex, mi, Expression.Constant("h"));

Expression<Func<People, bool>> expression =     
            Expression.Lambda<Func<People, bool>>(startsWith, param);

var searchData = (from s in people
             select s).Where(expression.Compile()).ToList();        
Both the Example 1 and Example 2 methods can be replace with the generics.

Friday, March 30, 2012

Cascading with jQuery AutoComplete

Source Code


In this post I am going to show how to achieve cascading functionality with the help of jQuery AutoComplete UI control rather than we are doing with the help of comobo-box controls till date.

By the following screen shot I am going to explain what I am going to achieve in this post and in later on post I am going to explain the part of the code did by me.

Screen 1: Loading Suggestion
When user start typing in country textbox  loader image shows that its loading suggestion for the character typed in textbox.

Screen 2: Display Suggestion
List of suggestion displayed to the end user , which is in turn fetch from the server.

Screen 3: Display State aftter country selection
Select State textbox get visible once user select country name from the suggestion list.

Screen 4: Display City after State selection
Select city textbox get visible once user select state name from the suggestion list.

Screen 5: Display Search button after selecting city
Search button get visible once user done with the selection of city name from the suggested cities.

Screen 6: Displaying Search data
Search Data get displayed in the gridview control once user click on search button.

Screen 7: "No Data Found" Error Message
Error message get displayed when user types in the textbox and suggestion is not available to display.

Screen 8: "Enter valid Data" Error Message

Alert Message of enter data get displayed when search button is press and one of the textbox value is not present.

Screen 9: "Enter valid Data" Error Message
Alert Message of enter data get displayed when search button is press and one of the textbox having value for which suggestion is not present.

As you can see in the screen shot when I type auto-complete functionality show me the suggestion and once I select suggestion , selected value get placed in the textbox and another row get visible which does the same functionality.

Now in the below post I am going to discuss about cascading thing with one textbox only but you can see whole by downloading the full source code of this post.

Aspx page i.e html markup
First start with the Aspx page, what the changes I did for the autocomplete textbox which is going to cascade other autocomplete textbox
<tr id="trCountry">
  <td>
   <label id="lblCountry" runat="server" text="Select Country" width="150px">   
   </label>
  </td>
  <td>
    <div style="float: left;">
TextBox id="txtCountry"
attached class="autosuggest", which tells that when you start typing in its going to display list of suggestion which fetched from the database using ajax and autocomplete plug-in.
<textbox class="autosuggest" font-size="10px" id="txtCountry" runat="server" 
                  width="250px"></textbox>
<span id="spCountry" style="display:none;color:Red;">No Data Found</span>
Span id="spCountry"
It get display when there is no suggestion avaialbe for the character typed in textbox.
<div style="display: none;">
As you see above div having style display=none that means the button and textbox both remains hidden when the page get display on browser.
Button id "btnCountry"
on click event get fire when of of the suggestion get selected. So this button fire up the server side event from javascript and make visible the next level textbox. How it fires the event
<button font-size="10px" id="btnCountry" onclick="btnCountry_Click" 
                runat="server" width="250px"></button>
TextBox id="txtCountryID"
this textbox stores the value of the country id which is going to be selected from the suggestion list.
<textbox id="txtCountryID" runat="server"></textbox>
       </div>
    </div>
  </td>
</tr>
this layout is same for the State and City next level selection textboxes that you can see in full source code.

jQuery/Javascript
Following is jQuery method that going be utilize for the showing the suggestion , which is provided by autocomplete plug-in.

autocomplete - method
method provided by the pug-in which is in turn get attach with the textbox control which than show the suggestion when user types in. In the above code its attached with the Country textbox, which is same for the State and city textbox that you can see in full code.
var pagePath = window.location.pathname;
         $(function() {

         $("#" + "<%=txtCountry.ClientID %>").autocomplete(
             {
Attribute of autocomplete
source - is from which suggestion will come up, as I am fetching data from the server side page/function I used jQuery ajax function to get the list from server.
Sucess - function attached with this attribute of the ajax function get the data for suggestion list as you can see if the data length is equal to 0 than it display span element which shows that data is not present.
source: function(request, response) {

                     $.ajax({
                     url: pagePath + "/GetCountry",
                         data: "{ 'id': '" + request.term + "'}",
                         dataType: "json",
                         type: "POST",
                         contentType: "application/json; charset=utf-8",
                         dataFilter: function(data) { return data; },
                         success: function(data) {
                             if (data.d.length == 0) 
                                 $("#spCountry").show();
                             else
                                 $("#spCountry").hide();
                             response($.map(data.d, function(item) {
                                 {
                                     value = item.Name + " : " + item.ID;
                                     return value;
                                 }
                             }))
                         },
                         error: function(XMLHttpRequest, callStatus, errorThrown) {
                             alert(callStatus);
                         }
                     });
                 },
minLength - no of char typed by use in textbox before the suggestion come up i.e after this many character typed by user than the source get query for suggestion. over here is having value 1 means its start showing suggestion once you start writing in it.
minLength: 1,
select - function associated with this attribute get fire when the use select the item from suggestion list. This is most useful function that do postback and do execute code on serverside by calling serverside button click function , button click function enable State row. As well as this break the string and assign text value to country textbox and id to countryid textbox which is hidden one and which value utilize by the state texbox to display suggestion.
select: function(event, ui) {
                     var str = ui.item.label.split(":");
                     $("#" + "<%=txtCountry.ClientID %>").val(str[0]);
                     $("#" + "<%=txtCountryID.ClientID %>").val(str[1]); 
                     $("#" + "<%=btnCountry.ClientID %>").click();
                 }
             });
         });

Validate function
The function get fire when user click on search button to search people resides in which city once done with selection of country,satate and city.
function Validate() {
      var retVal = true;
      if ($("#spCountry").is(":visible")||
            $("#spSatate").is(":visible") ||
            $("#spCity").is(":visible"))
          retVal = false;
      if($("#" + "").val()=="" ||
         $("#" + "").val()=="" ||
         $("#" + "").val()=="")
          retVal = false;
         if(!retVal) 
      alert("Enter Valid Data"); 
      return retVal;
  }
the code checks for is any of the span element associated with the textbox control is visible which display error message "No Data Found" and also check that is any on textbox contrains blank value. If its all proper it return true value otherwise return false.

CodeBehind Files - aspx.cs file
In cs file I designed class for the testing purpose the name of the class is Common which is going to be utilize by GetCountry, GetState and GetCity methods
public class Common
{
    public int ID { get; set; }
    public string Name { get; set; }
    public int ParentID { get; set; }
}
ID - is the unique value to detect each element uniquely.
Name - is value string value for each element.
ParentID - is value to detect element is child of which element.

People class is used to bind data with the gridview control once user press the search button.
public class People
{
    public string Name { get; set; }
    public string Email { get; set; }
    public int CityID { get; set; }
}
Name- name of the person
Email - email Address
CityID - is the id of city which user belongs.

As I explained before when user start typing in the textbox suggestion list come from the serverside method, following is the one of the method you find other in full code. GetCountry method get called when start typing in Country textbox.
[WebMethod]
    public static List GetCountry(string id)
    {
        try
        {
            List<common> country = new List<common> 
            {
                new Common(){ ID=1 ,Name = "India",ParentID=0 },
                new Common(){ ID=2 ,Name = "USA",ParentID=0 },
                new Common(){ ID=3 ,Name = "Ireland",ParentID=0 },
                new Common(){ ID=4 ,Name = "Australia",ParentID=0 }
            };
As I am going to call the method from server side its having attribute WebMethod. In the above code I initialize the collection of country and country is parent element all element have the parentid 0.
Method has parameter called id which is contains the value of the textbox which is typed in textbox. ajax calling function in source pass the id as json parameter to method that you can see in above method of jQuery/javascript.

List lstcountry =
                        (from c in country
                         where c.Name.StartsWith(id)
                         select c).ToList();
            return lstcountry;
 
        }
        catch (Exception ex)
        {
            return null;
        }
    }
Above code as you can see apply linq query on the collection and locate the match element which starts by the character typed in textbox.

Conclusion
So the above post demonstrate that its easy to achieve the cascading with the help of the auto suggest functionality provided by jQuery autosuggest plug-in.

Note : 
Find download code at the start of article and if you have any problem in downloading source code and if you have any query regarding this please mail me at : pranayamr@gmail.com or post comment at below.

Sunday, March 4, 2012

Most efficient way to update with LINQ to SQL

Question

Can I update my employee record as given in the function below or do I have to make a query of the employee collection first and then update the data?
public int updateEmployee(App3_EMPLOYEE employee)
      {
          DBContextDataContext db = new DBContextDataContext();
          db.App3_EMPLOYEEs.Attach(employee);
          db.SubmitChanges();
          return employee.PKEY;
      }
Or do I have to do the following?
public int updateEmployee(App3_EMPLOYEE employee)
    {
        DBContextDataContext db = new DBContextDataContext();
        App3_EMPLOYEE emp = db.App3_EMPLOYEEs.Single(e => e.PKEY == employee.PKEY);
        db.App3_EMPLOYEEs.Attach(employee,emp);
        db.SubmitChanges();
        return employee.PKEY;
    }
But I don't want to use the second option. Is there any efficient way to update data?

I am getting this error by using both ways:
An attempt has been made to Attach or Add an entity that is not new, 
perhaps having been loaded from another DataContext.  
This is not supported.

Answer

I find following work around to this problem :

1) fetch and update entity (i am going to use this way because it ok for me )
public int updateEmployee(App3_EMPLOYEE employee)
    {
        AppEmployeeDataContext db = new AppEmployeeDataContext();
        App3_EMPLOYEE emp = db.App3_EMPLOYEEs.Single(e => e.PKEY == employee.PKEY);
        emp.FIRSTNAME = employee.FIRSTNAME;//copy property one by one 
        db.SubmitChanges();
        return employee.PKEY;
    }
2) disble ObjectTrackingEnabled as following
// but in this case lazy loading is not supported
       
    
        public AppEmployeeDataContext() : 
            base(global::LinqLibrary.Properties.Settings.Default.AppConnect3DBConnectionString, mappingSource)
          {
                    this.ObjectTrackingEnabled = false;
           OnCreated();
          }
3) Detach all the related objects
partial class App3_EMPLOYEE
    {
        public void Detach()
        {
            this._APP3_EMPLOYEE_EXTs = default(EntityRef);
        }
    }

     public int updateEmployee(App3_EMPLOYEE employee)
    {
        AppEmployeeDataContext db = new AppEmployeeDataContext();
        employee.Detach();
        db.App3_EMPLOYEEs.Attach(employee,true);
        db.SubmitChanges();
        return employee.PKEY;
    }
4) use Time stamp in the column

http://www.west-wind.com/weblog/posts/135659.aspx


5) Create stored procedure for updating you data and call it by db context

Find Actual Question and Answer at : http://stackoverflow.com/questions/2872380/most-efficient-way-to-update-with-linq-to-sql

Monday, October 24, 2011

DataLoadOptions and How to use in Compiled Linq query

DataLoadOption in LINQ allows immediate loading and filtering of related data. The DataLoadOption allow to load related object so this remove need of the firing subquery every time you ask for the related object(s).

Consider below case

If you do code like this
var distlist = (from d in edb.Distributors select d).ToList();
            foreach(Distributor d in distlist)
            {
              var clientlist = d.Customers;
              foreach( Customer c in clientlist)
              {
                   //do the code 
              }
            }
each time inner for loop fire query on database to get the customer related to distributor which in turn decrease the performance. But if you know in advance that you are need to use the related list when you are loading main list i.e you need to load data of related entity eagerly make use of DataLoadOptions.

Modified code is something like
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<Distributorgt;(d => d.Customers);
dataContext.LoadOptions = dlo;
Note
  • Be careful when you use DataLoadOption because it may decrease the performance if you are not going to use related objects. Use only in situation when you want to load related object early and going to consume it all.
  • You an only attach DataLoadOption once with the instance of datacontext.

The above DataLoadOption runs perfectly when you use regular Linq Queries. But it does not work with compiled queries. When you run this code and the query hits the second time, it produces an exception:

DataLoadOptions in Complied queries
First to get more info about Complied look this post : Increase Linq query performance by Compling it
Now when you attache DataLoadOption to complied query as we did above it give you an exception at run-time
Compiled queries across DataContexts with different LoadOptions not supported

To avoid the exception you need to create the static DataLoadOption variable because as the compiled linq queries are the static one it not consume the DataLoadOption which is not static.

So for that I have created below code where GetDataLoadOpt() static function returns DataLoadOptions object and I store it into static variable dlo and than attach this dlo1 with the compiled version of query.

public static DataLoadOptions dlo1 = GetDataLoadOpt();

    public static Func<DataLoadTestDataContext, string, IQueryable<Product>>
        ProductByCategory =
        CompiledQuery.Compile((DataLoadTestDataContext db, string category) =>
        from p in db.Products where p.Category == category select p);

    public static DataLoadOptions GetDataLoadOpt()
    {
        DataLoadOptions dlo = new DataLoadOptions();
        dlo.LoadWith<Product>(p => p.ProductWithCategory);
        return dlo;
    }

    public static void testfunction()
    {
        DataLoadTestDataContext context = new DataLoadTestDataContext();
        context.LoadOptions = dlo1;
        var productlist = ProductByCategory(context, "mobile");

        foreach (Product p in productlist)
        {
            Console.WriteLine(p.ProductWithCategory);
        }
    }
If you want to get the above exception try code removing static from the function testfunction and variable dlo1 than assign it to compiled version of query you will get the run-time exception.