smart developer’s blog

This is a C# resource library! Free how to’s and best practices…

Posts Tagged ‘linq

Linq in DataSet

with 2 comments

I recently had to filter and order some datasets. I used Linq and I found it to be very nice.
Here are a few examples:

1. If you have a dataset with a table containing products and you want to search for all products having “test” in their name, and order the list by creation date, you can use something like:


DataTable dt = ds.Tables[0]
			.AsEnumerable()
			.Where(o => o.Field<string>("Name").Contains("test"))
			.OrderBy(o => o.Field<DateTime>("CreationDate"))
			.CopyToDataTable();

2. Alternatively, if you have to order a report each time a column name is pressed, you can write you own method that orders a table by a given column:


private DataTable OrderDataTable<T>(DataTable dt, string orderby, string orderdir)
	{
	if(orderdir == "ASC")
		return dt.AsEnumerable().OrderBy(o => o.Field<T>(orderby)).CopyToDataTable();
	else
		return dt.AsEnumerable().OrderByDescending(o => o.Field<T>(orderby)).CopyToDataTable();
	}

and you can use it like this:


switch (orderby1)
	{
	case "Keyphrase":
		repMain.DataSource = OrderDataTable<String>(ds.Tables[0], orderby1, orderdir1);
		break;
	case "KEI":
		repMain.DataSource = OrderDataTable<Double>(ds.Tables[0], orderby1, orderdir1);
		break;
	default:
		repMain.DataSource = OrderDataTable<Int32>(ds.Tables[0], orderby1, orderdir1);	
		break;
	}

Have fun!

Written by smartdev

May 8, 2009 at 9:36 am

Posted in .Net, Programming

Tagged with , , ,

XPath vs Linq to XML

leave a comment »

Considering you have an xml file:


<Categories>
	<Category id="543" parentid="193" name="Bridal Jewellery & Accessories" treeactive="True">
		<Products>
		<Product id="6843" name="Pearl & Diamante Set">
			<Description><!&#91;CDATA&#91;Necklace and earrings with pearl style stones and diamante.</br>
Available in a choice of colours.</br>
Lifetime plating guarantee.&#93;&#93;></Description>
			<Stock>0</Stock>
			<Manufacturer>89</Manufacturer>
			<Supplier>A90/75043</Supplier>
			<Price>0.0000</Price>
			<RRP>0.0000</RRP>
			<CreationDate>01/01/0001 00:00:00</CreationDate>
			<Promo>False</Promo>
		</Product>
		<Product id="6844" name="Pearl & Diamante Set 2">
			<Description><!&#91;CDATA&#91;Necklace and earring set with diamante and pearl style stones.</br>
Lifetime plating guarantee.&#93;&#93;></Description>
			<Stock>0</Stock>
			<Manufacturer>89</Manufacturer>
			<Supplier>A90-75002</Supplier>
			<Price>0.0000</Price>
			<RRP>0.0000</RRP>
			<CreationDate>01/01/0001 00:00:00</CreationDate>
			<Promo>False</Promo>
		</Product>
	</Products>
	 </Category>
</Categories>

Basically there are two ways of querying XML files form C#:

1. The first one would be to use a XPath expresion. There are a few methods in System.Xml.XPath namespace (XPathEvaluate() which returns an object type, XPathSelectElement() which returns an XElement type and XPathSelectElemens() wich returns IEnumerable) that you can use.

For instance, in order to get all products containing “Pearl” in the product name, we will use something like this:


XmlReader reader = XmlReader.Create(filename);
XElement root = XElement.Load(reader);
reader.Close();
IEnumerable<XElement> children = root
				.XPathSelectElements("/Category/Products/Product[contains(@name,'Pearl')]");

2. Another way would be to use Linq to XML. The query is more complicated and not so compact as the XPath expression:


XmlReader reader = XmlReader.Create(filename);
XElement root = XElement.Load(reader);
reader.Close();
IEnumerable<XElement> children = root.Descendants("Category")
				.Descendants("Products")
				.Descendants("Product")
				.Where(o => o.Attribute("name").Value.Contains("Pearl"));

or


from xElem in root.Descendants("Category").Descendants("Products").Descendants("Product")
where xElem.Element("name").Value.Contains("Pearl")
select xElem;

I personally prefer to use XPath because it is more clearer. And sometimes there are queries that I couldn’t translate in Linq.

Lately, I was preocupied by the performance of each method and I was curios to find out which one is faster (for different sizes of xml files). So, I generated three xml files (small, medium and big) and tested 14 instructions on each file using both XPath and XML to Linq.

Unfortunatelly, we don’t have a clear result. Basically all times are the same no matter what we use – Linq or XPath. So, for now I guess I will stick to XPath only because it is more clearer :).

You can run the application here: http://seven.webme.ro/xpath/

xml_xpath

Written by smartdev

April 15, 2009 at 4:11 pm

Posted in .Net, Programming

Tagged with , ,

Serialize Linq objects

leave a comment »

If you are trying to serialize Linq objects then you will have to foolow these steps:

1. First, you have to mark your data context as serializable:

serialization_mode

2. Then, in order to avoid errors like “circular reference was detected while serializing an object of type…”, you will have to set “Access” to “Internal” on your object’s relations (It is a compromise, but it needs to be done):

step2_1        step2_2

3. You can now use these methods:


public static string Serialize(object o)
	{
		XmlSerializer serizer = new XmlSerializer(o.GetType());
		StringBuilder sb = new StringBuilder();
		StringWriter sw = new StringWriter(sb);
		serizer.Serialize(sw, o);
		sw.Close();
		return sb.ToString();
	}

public static T Deserialize<T>(string xml)
	{
		XmlSerializer serizer = new XmlSerializer(typeof(T));
		StringReader sr = new StringReader(xml);
		return (T)serizer.Deserialize(sr);
	}

like this (example):


AddressBookDataContext data = new AddressBookDataContext();
string xml = LINQHelper.Serialize(data.AB_Offices.ToList());
//..
List< AB_Offices>list = LINQHelper. Deserialize<List<AB_Offices>>(xml);

It works!

Written by smartdev

April 3, 2009 at 4:01 pm

Posted in .Net

Tagged with , ,