1

I'm using System.Linq.Dynamic to query an IQueryable datasource dynamically using a where-clause in a string format, like this:

var result = source.Entities.Where("City = @0", new object[] { "London" });

The example above works fine. But now I want to query on a foreign key-property of type Guid like this:

var result = source.Entities.Where("CompanyId = @0", new object[] { "838AD581-CEAB-4B44-850F-D05AB3D791AB" });

This won't work because a Guid can't be compared to a string by default. And I have to provide the guid as a string because it's originally coming from a json-request and json does not support guid's.

Firstly, is this even a correct way of querying over a relationship or is there an other syntax for doing this?

Secondly, how do I modify Dynamic.cs from the Dynamic Linq-project to automatically convert a string to guid if the entity-property being compared with is of type guid?

svick
  • 236,525
  • 50
  • 385
  • 514
Andreas Zita
  • 7,232
  • 6
  • 54
  • 115
  • why you pass string as parameter instead of Guid? try use `Guid.Parse` and pass guid – Grundy Feb 08 '14 at 12:23
  • As I wrote, the query is coming from a json-request and I can't go through a convert possible guid-strings to guids. It would be best if the Dynamic.cs could be modified to detect when I try to compare a Guid with a string and do the conversion then instead. – Andreas Zita Feb 08 '14 at 12:29

1 Answers1

1

You have many ways for solving. Simplest, as i think, will be change your query like this

var result = source.Entities.Where("CompanyId.Equals(@0)", new object[] { Guid.Parse("838AD581-CEAB-4B44-850F-D05AB3D791AB") });

If you want use operators = and == then in Dynamic.cs you need change interface IEqualitySignatures : IRelationalSignatures like this

interface IEqualitySignatures : IRelationalSignatures
{
    ....
    F(Guid x, Guid y);
    ....
}

after that you can use next query

var result = source.Entities.Where("CompanyId=@0", new object[] { Guid.Parse("838AD581-CEAB-4B44-850F-D05AB3D791AB") });

OR

var result = source.Entities.Where("CompanyId==@0", new object[] { Guid.Parse("838AD581-CEAB-4B44-850F-D05AB3D791AB") });

But if you want use string parameter you need change ParseComparison method in ExpressionParser class. You need add yet another checking for operand types like this

....
//you need add this condition
else if(left.Type==typeof(Guid) && right.Type==typeof(string)){
    right = Expression.Call(typeof(Guid).GetMethod("Parse"), right);
}
//end condition
else {
    CheckAndPromoteOperands(isEquality ? typeof(IEqualitySignatures) : typeof(IRelationalSignatures), op.text, ref left, ref right, op.pos);
}
....

and then you query will be work

var result = source.Entities.Where("CompanyId = @0", new object[] { "838AD581-CEAB-4B44-850F-D05AB3D791AB" });
Grundy
  • 13,356
  • 3
  • 35
  • 55