December 2007 - Posts
Since, the first release of LinqExtender, I found quite a bit download and feedback from community around. I did plenty of changes and tried to make it as simple as possible for creating custom providers without knowing a bit of reflection and expression parsing of the core framework.
After the release , I was asked by people around that why do we need LINQ when we can do it by method calls. The answer to it is, LINQ gives another level of abstraction to method call that enables you to set a query domain for developers, by means of strongly type query objects, it's not like exposing the data access layer to the front end developer, but it is like giving them a playground with proper boundary. In other words, front end developers now can query on some specific criteria that we set by means of query object , still giving them a flexibility of functional programming.
Now on to the release 1.2. it has come with query info retrieval wrapper and some new features ,which could be useful while making custom providers.
I have mentioned in following post, how query data is delegated to Process routine, that will be overridden in the custom provider that developer is working on.
http://weblogs.asp.net/mehfuzh/archive/2007/12/02/linqextender.aspx
Now with new release it looks something like
protected override void Process(LinqExtender.Interface.IModify<T> items, Bucket bucket)
As , you can see that it has Bucket object, which is nothing but a wrapper for holding the query details. Each Bucket has some BucketItem. BucketItem contains info for each property used in the expression separated by &&.
Typically BucketItem looks like
BucketItem
Name - Property name, different if the used with OriginalFieldNameAttribute, or less it is same as property name.
Value - value in the query , for which the property is compared. Default value, Null.
Unique - True , if UniqueIdentifierAttribute or its inherited type is used on property.Here, one can Use UniqueIdentifierAttribute directly on property or can use any inherited form like, PrimaryKeyAttribute that inherits the UniqueIdentifierattribute, to reflect value to this property.
RelationType : Enum - Equal , LessThan, LessThatEqual, GreaterThan, GreaterThanEqual. Used to identify which type of logical comparison is used.
Any of the property, which is not used in a query , BucketItem.Value and BucketItem.RelationType will have the default value for it, which is Null and Equal respectively.
Now, Going Back to Bucket it looks like
Bucket
IDictionary<string, BucketItem> Items - List of items for property, where string is the property name of the query object, BuckItem represents how the Property is treated and used in query.
ItemsToTake - default null , if Take is not specified in query.
ItemsToTake - default 0, if Skip is not specified in query.
UniqueItems - string[], contains the name of property on which UniqueIdentifierAttribute or its derivative is applied.
As, we can see from this release that Linqextender supports most common logical expression rather than just Equal expression.
The new release also supports "New Type" queries, which i already mentioned in this post
http://weblogs.asp.net/mehfuzh/archive/2007/12/16/anonymous-type-in-linqextender.aspx
Finally, I have added CTE(Common table expression) generation for OpenLinqToSql (Formerly known as TinyLinqToSql) provider.
Now , queries like the following with Take and Skip
SqlQuery<Book> context = new SqlQuery<Book>();
var query = (from q in _queryContext
orderby q.LastUpdated ascending
select q).Take(5).Skip(2);// this is where the query will execute
foreach(var book in query)
{
// do something useful
}
Will generate Sql like...
WITH FilteredList(Id,Author,Title,ISBN,LastUpdated, [RowNumber]) AS(
SELECT Id,Author,Title,ISBN,LastUpdated, Row_number()OVER(ORDER BY
LastUpdated asc) as [RowNumber] FROM Book
)Select * from FilteredList WHERE [Rownumber] Between (3) and (7)
Here, Take(5), Skip(2), it will take 5 items starting from 3.
For more, I would suggest to have a look at release page of LinqExtender
OpenLinqToSql provider is made to exercise the LinqExtender engine , it is provided with the LinqExtender source and with NUnit test class in LinqExtender project itself. There is another project named Linq.Flickr, where I have originally started working on with Linq provider and then made LinqExtender, this is currently a separate project. This shows another possible implementation of LinqExtender for service end points.
Happy Holidays!!!
It is now possible for LinqExtender implemented providers to have anonymous type in the select query.
For example, consider the following
SqlContext<Book> context = new SqlContext<Book>();
var query = (from q in context
orderby q.LastUpdated descending
select new { q.ISBN, q.Title}).Take(1);
var book = query.single();
// do something useful
Console.WriteLine (book.ISBN + " " + book.Title);
This sample done using TinyLinqToSql custom provider made on LinqExtender. Here I have some books in database and i want the top 1 , latest book out of it, also I need only two items, ISBN and Title, which I just need to show to in my current scope, without declaring any formal type, in this case the anonymous type can be useful and can be done in the above way.
By the time , I am writing this post , I was having some problem with codeplex , for uploading the latest code of LinqExtender. Hope , it will be done , when you are reading this post.
Also, I have uploaded a new version Linq.Flickr , with latest LinqExtender, so you can have the taste of anonymous type in there as well. Though this is out of scope of the post, but need to say that, now you can get photos with order by Date_Posted/ Date_Taken asc/dsc respectively. Flickr API also supports, other two properties Relevance and Interestingness, but these two only support sort by ascending , therefore , I omitted this half feature, hope they will come with both way order for these two parameters.
No need to say, you can download Linq.Flickr at www.codeplex.com/linqflickr and LinqExtender and TinyLinqToSql at www.codeplex.com/linqextender
Also, I found this cool post of Scott Gutherie for anonymous type, you might need to look at it as well.
http://weblogs.asp.net/scottgu/archive/2007/05/15/new-orcas-language-feature-anonymous-types.aspx
Finally, an anon but cool guy from community named Reski Mills helped me implement this anon type real fast, thanks man!
Enjoy!!

I have released the new version of LinqExtender, it now support orderby queries
Like I can easily do
var query = from q in context
where q.Id == 1
orderby q.Id descending
select q;
Also, I have uploaded a tiny linq to sql project named OpenLinqToSql which is built on LinqExtender and can be downloaded from LinqExtender release page
To start working with OpenLinqToSql, all is needed.
First create a object that represents the entity class.For example , i have created a Book table in database , which looks like
CREATE TABLE [dbo].[Book](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Author] [nvarchar](255) NOT NULL,
[Title] [nvarchar](255) NOT NULL,
[ISBN] [nvarchar](50) NOT NULL,
[LastUpdated] datetime NOT NULL
)
For which the representation of object is
class Book : QueryObjectBase
{
[LinqVisible, Identity]
public int? Id { get; set; }
[LinqVisible]
public string Author { get; set; }
[LinqVisible]
public string Title { get; set; }
[LinqVisible]
public string ISBN { get; set; }
[LinqVisible]
public DateTime? LastUpdated {get; set;}
public override bool IsNew
{
get
{
return Id == null;
}
}
}
Here to note that, in order to use a property in query expression, LinqVisibleattribute is used. Also, Non string properties, should be made Nullable.
Finally, I can do the following to get things going
SqlQuery<Book> context = new SqlQuery<Book>();
Write the query.
var query = from q in context
orderby q.Id descending
select q;
The OpenLinqToSql can talk with SQLCE databases as well. Also, this is just an tiny project that helps to understand how to make providers using LinqExtender, but for real flavor , use the LinqToSql that comes with .net 3.5
Thanks
We have seen that , while making general LINQ query provider , we have to implement IQueryable along with IQueryProvider.
But what about the following query.
var query = (from ph in context.Photos
where ph.User == User && ph.PhotoSize == PhotoSize.Medium
&& ph.SearchText == "pocketpc, windows mobile" &&
ph.SearchMode == SearchMode.TagsOnly orderby PhotoOrder.Date_Posted descending
select ph ).Take(10).Skip(0);
As, this query has orderby clause, this will require IOrderedQueryable instead of IQueryable, or less it will end up with build error.
Now, digging deeper, what is the methodcall for orderby "item" descending/ascending
Simple order by , like orderby ph.id / orderby ph.id ascending, the internal method call is OrderBy(ph=>ph.id)
Query
var query = from ph in context.Photos where ph.user = "jcl"
order by ph.Date_Taken select ph;
but if we use, orderby p.id descending , the internal method call will be made as OrderByDescending(ph => ph.id).Therefore, in CreateQuery<T>, we have to check for OrderByDescending and OrderBy method separately to process data accordingly.
Which could be
MethodCallExpression curentMethodcall = _expression as MethodCallExpression;
_asc = curentMethodcall.Method.Name == CallType.ORDERBYDESC ? false : true;
ProcessExpression(curentMethodcall.Arguments[1], _dummyPhotoObject);
And during ProcessExpression , the expression breakdown will be
UnaryExpression
LamdaExpression
Memberexpresion ( for p = > p.id) or direct ConstantExpression (for p=> "Dake_take")
Source : LinqExtender
Hope this is useful

The greatest capability for LINQ is extensibility, My Linq.Flickr api shows how to create , add and quey photos from flickr , without knowing a bit of complexity that is underlying. But, there can be many other need for custom query providers like, Linq to facebook, Linq to youtube, etc. So, creating all these , could be very easy and fun, if there is a common framework that will sit between core Linq and custom provider and let developers to focus only on the application specific logic, not on the query internals and thus it will help developers to make their own providers up and running, in no time.
This is where, it comes a toolkit called LinqExtender that will gear you up for creating custom provider, with zero complexity.
To start off with LinqExtender, you can either use the VSI installer or LinqExtender.dll.zip, both of which are referenced in release page of the project.Also, following lines will show , what is needed to start developing custom providers.
--
Create a query object, on which the query will be made , by inheriting QueryObjectBase and overriding the IsNew property , which is used to track , if the object is newly added to the collection or not and this will be tracked during , add/ update of query obejcts,
For example, for the following code , the IsNew property will have value "true"
MyProvider context = new MyProvider ();
context.Add(MyObject);
context.SubmitChange();
Code sample of CustomQuery object, in this case MyObject
public class MyObject : QueryObjectBase
{
public override bool IsNew
{
get
{
//TOOD : Add your own Is New logic.
return true;
}
}
}
Now, Create the custom query provider by inheriting Query<T> and overriding some methods of it. In this case the code sample looks like
public class MyProvider : Query<MyObject>
{
protected override void AddItem(MyObject item)
{
// TOOD : Implenment data access logic,
// Sample
// IFlickr flickr = new DataAccess();
// flicrk.Add(item);
}
protected override void RemoveItem(MyObject item)
{
// TODO : Implement data access logic
//Sample
// IFlickr flickr = new DataAccess();
// flicrk.Delete(item);
}
protected override void Process(LinqExtender.Interface.IQuery<MyObject> items,
MyObject bucket, int itemsToTake, int itemsToSkip, bool isParamCall)
{
// TODO : populate collection on basis of bucket object.
// Sample
// IFlickr flickr = new DataAccess();
// IList<Photo> list = flicrk.SearchPhoto(bucket.SearchText, bucket.User, itemsToSkip, ItemsToTake);
// items.AddRange (list);
}
}
Here to note that bucket variable in Process method, is filled up the query value that is made by user . In the case of Linq.Flickr , when user does a photo query in the following way
var query = (from ph in context.Photos
where ph.User =="jcl"&& ph.PhotoSize == PhotoSize.Medium
&& ph.SearchText == "pocketpc"
select ph).Take(10).Skip(0);
Inside Process the bucket will have the following values
bucket.SearchText = "pocketpc"
bucket.PhotoSize = PhotoSize.Medium
bucket.User = jcl
In the query you can also see that for Take and Skip , itemsToTake and ItemsToSkip will be filled up respectively and IsParamCall = true , if the query has no Where cause.At the end of the method items variable, needs to be filled up with the result, in this case, list of photos. Therefore, at the end of Process , items.AddRange or items.Add should be used to reflect the result back to query.
Finally, The AddItem/ RemoveItem method is called , when user adds / removes an item, then make SubmitChanges() call.
--
This is a short introduction to LinqExtender, in coming weeks, I will write more walkthroughs with working sample. For now, to see the real implementation , take a look at Linq.Flickr project.
Enjoy!
Starting with 1.1 version rather working with main object refernce in AddItem , RemoveItem and Process , a new wrapper name Bucket is introduced to deal with query parameters to have a unified and extensible way of dealing with user query details. Please check the codeplex project page for more Info. Also, see the prograssion of posts made with this blog as well.
More Posts