Mats just posted another of his dead sea scroll posts about the new features he have added to NPersist.
(Yes, while I have been slacking and playing with Lisp)
Tag Archives: O/R Mapping
Making a custom Linq engine
You can download the complete source here
NOTE: The download contains much more than this post.
Today I’m going to show how to make a custom linq engine.
So, why would you want to create your own engine?
Well replicating the standard in mem engine is pretty pointless except for educational purposes.
But you might need custom engines for your own frameworks where you want to query your own special DB or media of some sort.
We use this in NPerist, we transform the linq query into our own NPath DSL and then run the NPath query through NPersist into the database.
Anyway, back to the sample.
Lets start by creating a simple console application and add the following code in the Main method:
using System.Linq;
...
...
...
//setup test data
List<string> source = new List<string>() {
"public",
"protected internal",
"void",
"static",
"for",
"string",
"int",
"long",
"List<T>"
};
//run a simple query
var result = from item in source
where item.Length > 1
select item + " hello linq"; //display the result
Console.WriteLine();
Console.WriteLine("Result:------------------------");
foreach (var item in result)
{
Console.WriteLine("{0}", item);
}
Nothing fancy, we simply init a list with a few strings, and then we run a standard linq query on it.
Now lets start writing our own Linq engine.
To do this we need a few delegates:
// T = item type // IN = item type IN // OUT = item type OUT //delegate to handle the where clause public delegate bool WhereFunc<T>(T type); //delegate to handle the select clause public delegate OUT SelectFunc<IN, OUT>(IN item);
We also need two extension methods:
namespace MyLinqEngine;
{
public static class Sequence
{
//extension method that will handle where clauses
public static List<T> Where<T>
(this List<T> source, WhereFunc<T> matchDelegate)
{
//create a result list
List<T> result = new List<T>();
//scan all items in the source
foreach (T item in source)
{
//check for match
bool match = matchDelegate(item);
if (match)
{
//add match to result
result.Add(item);
}
}
return result;
}
//extension method that will handle select clauses
public static List<OUT> Select<IN, OUT>
(this List<IN> source, SelectFunc<IN, OUT> selectorDelegate )
{
//create a result list
//since the result will have the exact same size as
//the source we can init it with a fixed size
List<OUT> result = new List<OUT>(source.Count);
//scan each item in the source
foreach (IN item in source)
{
//transform the items in the source to an
//item of the given out type
OUT resultItem = selectorDelegate(item);
result.Add(resultItem);
}
return result;
}
}
}
And that’s it!
That’s all you need in order to create the simplest form of custom Linq engine.
The default Linq extensions are activated by the “using System.Linq;” at the top of your program.cs class file.
We can now remove that line and replace it with “using MyLinqEngine;” in order to activate our own linq extensions.
You’ve now got your very own debuggable Linq engine.
Happy coding.
//Roger
You can download the complete source here
NOTE: The download contains much more than this post.
ORM and C#3 anonymous types
Here goes my first blog post in 1+ years.
Nowadays I’m playing around with VS 2008 trying to abuse all the new features as much as possible.
Earlier today I was talking to Mats Helander about making a NPersist v3, for .NET 3.5.
We were discussing new features such as supporting anonymous types instead of our old “Tabular” concept.
After a while I started to think about the possibilities to use anonymous types to create read only views for stored procs,
and I came up with a quite slick solution ( in my own opinion OFC ;-) )
Anyway, here is what I came up with:
//create a prototype for our result
var prototype = new { FirstName = "" , Age = 0 , Email = "" };
//fill a list with items of the above type with data from an sproc
var res = MyDal.ExecuteStoredProc(prototype, "sp_MyStoredProc", p1, p2, p3);
//present the data in our top notch UI
foreach (var item in res)
{
Console.WriteLine("FirstName = {0}", item.FirstName);
}
What I do here is:
I create an object of an anonymous type, which will act as a prototype for our result.
The anonymous type contains our properties and the type for each property.
Then I pass the prototype object into my DAL and ask my DAL to execute an stored procedure with some args.
The DAL executes procedure and fill a generic list of my anonymous type with the result.
And then return the filled list the consumer.
This allows the consumer to call a stored procedure and get the result in an objectified way.
Making it possible to work with his data in a typed way w/o adding typed datasets or entity classes.
OK, the anonymous type is a sort of entity class too.
But since it can be designed per use case, you do not have to clutter the project with loads of view specific classes.
Well that’s it for now.
Full sample code will be provided soon.
//Roger