ITmeze - IT world server like cyprus meze

Recent blog posts Tagged 'linq'

System.Linq.Dynamic and Spatial Searches


On my current project i am doing a LOT of dynamic searches. 

Lot's of them go through System.Linq.Dynamic library - it is really just one .cs file. As library has lost somewhere on internet, the only place i have managed to find it is on one of github's repository :

I had to run some spatial searches over exposed DbGeography type - those are directly on database - via Entity Framework

public class Town { public string Name { get; set; } 
public DbGeography Location { get; set; } } 

The problem is, dynamic queries (based on string) simply won't work on that.

_db.Towns.Where("Location.Distance(@0) < 20000", someLocation).ToList() 

Such query will bruttaly fail with "Methods on type 'DbGeography' are not accessible". Going through the code shows us:

if (!IsPredefinedType(method.DeclaringType))

is throwing exception. Solution for that is simple and requires to add DbGeography to 'predefinedTypes' variable. Now, following test will pass:

public void DistanceSearchShouldWork()
	var warsaw = new Town() { Name = "Warsaw", Location = DbGeography.FromText("POINT(52.229718 21.012214)") };
	var lodz = new Town() { Name = "Lodz", Location = DbGeography.FromText("POINT(51.759304 19.455969)") };
	var berlin = new Town() { Name = "Berlin", Location = DbGeography.FromText("POINT(52.523206 13.410836)") };
	var towns = new List

	var distance = warsaw.Location.Distance(lodz.Location);

	Assert.Equal(1, towns.Where("Location.Distance(@0) < 20000", warsaw.Location).Count());
	Assert.Equal(2, towns.Where("Location.Distance(@0) < 200000", warsaw.Location).Count());
	Assert.Equal(3, towns.Where("Location.Distance(@0) < 2000000", warsaw.Location).Count());

In case you would like to grap solution directly - you can do that on fork here.


Tags: [linq] [DbGeography] [spatial]

LINQ Enumerable.Agregate with Path.Combine


Path.Combine accepts two parameters. Just two... So when we combine multiple path we have to deal with with nesting of Path.Combine:

string rootDir = "/root/app";
string folder1 = "users";
string folder2 = "mike/upload";
string filename = "text.xml";

var path = Path.Combine(rootDir, Path.Combine(folder1, Path.Combine(folder2, filename)));

There are 2 ways to handle this: 1. Use Enumerable.Agregate:

string rootDir = "/root/app";
string folder1 = "users";
string folder2 = "mike/upload";
string filename = "text.xml";

var path2 = new string[] { rootDir, folder1, folder2, filename }.Aggregate(Path.Combine);

2. Or upgrade to .NET 4.0 where there is an overload with Path.Combine(params string[] paths) :) Have fun!

Tags: [.net] [linq] [programming] [web development]

Copyright 2013 © ITmeze