« Syntax Highlighting in Typepad | Main | Using the dynamic Keyword in C# to Improve Object-Orientation »

26/05/2010

Comments

Feed You can follow this conversation by subscribing to the comment feed for this post.

www.codinginlondon.com

I find Linq very useful too... I started using it to do some lightweight data crunching on a C# client. I'm also planning to migrate our layer of stored procedures wrappers from ODBC (C++) to Linq (C#). So far Linq is the easiest way I know to wrap stored procedures calls...

http://www.codinginlondon.com/2010/03/comparing-result-sets-with-linq.html

Walter Almeida

Hello Matthieu,
Yes Linq is great, I especially love Linq to objects! But I am not too sure about Linq to SQL. I would suggest you to have a look at Linq to Entities. Linq to SQL has limits and is not a proper ORM as such. Linq to Entities is a proper ORM. Or more precisely: the Entity Framework is an ORM and Linq to Entities is the way to query the Entity Framework (the same way you have a Linq to LLBLGenPro: the ORM I am using). Linq to SQL IMHO is not the most robust, scalable and evolutive solution you could possibly use.

Thomas Levesque

Hi Walter,

Great article, thanks ! This is exactly what I was looking for.

Just one remark : you also need to update the CreateKeywords method, to add "outerIt" to the list of known keywords

Walter Almeida


Hi Thomas!

Thanks for your comment, and I am happy to hear that this work helped you.

Oh yes you're right, CreateKeywords has to be updated. It is done in the source code attached to the post. However I forgot to mention it in the post itself. So thanks for that!

And if you're doing some work on dynamic linq, I am happy to hear about it if you want to share, as there are not too many people investigating this.

Sean Brauen

Mad props for this figuring this out, it really saved me. I've referenced your post as the answer in an ASP.NET forum post I had regarding this very issue.

Thanks again!!

Walter Almeida

Thanks for your comment Sean, and for referencing my post. I am glad it helped you!

Sean Brauen

Walter,

I had a couple of problems on my end I needed to work through, but now I'm getting this error:

LINQ to Entities does not recognize the method 'Boolean Contains[Guid](System.Collections.Generic.IEnumerable`1[System.Guid], System.Guid)' method, and this method cannot be translated into a store expression.

I'm not sure if I did something wrong or not and was wondering if you could help out. Below is the Where clause I'm using where @0 = List and @1 = Guid, both values do exist.

IS_DELETED==false && @0.Contains(outerIt.URI) && (DESIGNER_COUNTRY_ID.URI.Equals(@1) || SPECIFIC_USER_VARIANT_ID.URI.Equals(@1))

Thanks!

Walter Almeida

Hello Sean,

I am not using Linq to entity framework but Linq to Llblgen and it is working fine...

After a quick search on internet it seems that Linq to EF does not support Contains extension!
So another solution has to be found. I am on holiday right now, I will check more on your issue when I am back next week.

Walter Almeida

Hello Sean,

After checking, EF v4 Supports the "Contains" extension method (thanks Frans Bouma for helping me with this!).

So the solution to your problem should be to upgrade to EF v4, you apparently are using the previous version, aren't you?

Vlad

Hello Walter, wery intresting post!

And is there any way to make dynamic library support Select method?

For example to use in queries like
var r1 = Query.All().Where(a => a.Roles.Select(b => b.Role.Name).Contains("admin"));
as
var r2 = Query.All().Where("Roles.Select(Role.Name).Contains('admin')");

model (DataObjects.NET) is:

[Serializable]
[HierarchyRoot]
public class User : Entity
{
[Field, Key]
public int Id { get; private set; }

[Field(Length = 100)]
public string Name { get; set; }

[Association(PairTo = "User")]
[Field]
public EntitySet Roles { get; private set; }
}

[Serializable]
[HierarchyRoot]
public class UserInRoles : Entity
{
[Field,Key]
public int Id { get; private set; }

[Field]
public User User { get; set; }

[Field]
public Role Role { get; set; }
}

[Serializable]
[HierarchyRoot]
public class Role : Entity
{
[Field, Key]
public int Id { get; private set; }

[Field(Length = 100)]
public string Name { get; set; }

[Association(PairTo = "Role")]
[Field]
public EntitySet Users { get; private set; }
}

Walter Almeida

Hello Vlad,
Thanks for your comment;)
Well, that should be possible, however becoming tricky. You could potentially find other ways to do what you are trying to achieve.

For example what about overriding Equals() in the Role Entity, and returning true when role name is same.

and then write your query like this:
var r2 = Query.All().Where("Roles.Contains(@0)", new Role() { Name = "admin" });

Will work the same in an neater way:)
I haven't tested yet though, you should try. But you get the idea

yazid

Hello,

Excellent article, how about if I had a dynamic object. How would I use it. Would it work?

Thx
Yaz

Axel

Hi,
Nice article ! Really helpful !
I'm now trying to do the same to handle the "Take" method, but I can't get it working. Maybe you can help ?
Thanks.
Axel

Andrei

Good stuff. However, I'm having a problem where it fails if the search item has spaces. I see your example works fine for "Dominican Republic". However, in my code, any time I have a value with a space, it doesn't find it. The only difference is I'm using VB.NET.

Andrei

Nevermind. Strangely what I thought was the most common value in my data source doesn't even exist in there! It works great! Thx!

Stefan

Thx for this, was looking for it for quite some time!

I have, however, issues when I try this on a Datetime field. Say I want to search for a couple of dates:
I've tried using List as parameter, but not working.
I've tried using List with all values in YYYY-MM-DD format as parameter, but not working, because I cannot seem to convert the column of the queryable object to string.

Any thoughts?


Stefan

I see that part of my comment is lost. What I meant was:

I've tried using List of Datetime as parameter, but not working.
I've tried using List of string with all values in YYYY-MM-DD format as parameter, but not working, because I cannot seem to convert the column of the queryable object to string.

A Facebook User

Hi Walter
Thanks for the code lesson, i learnt alot!
I do have one question before i implement this if you don't mind.

If i followed your code example to add a StartsWith extension, would it be able to pass extra arguments for case insensitive query. (I tried, but got some parsing errors and then got lost in the code)

here's an example of what i'm trying to achieve

query = Contact.GetContactsList().AsQueryable().Where("@0.StartsWith(outerIt.Country, StringComparison.InvariantCultureIgnoreCase)", new List() { "austria", "poland" });

any help greatly appreciated.
thanks Peter

priya

i tried this but i get the following error still.

No property or field 'outerIt' exists in type 'String'

Alex Harbers

Priya,

You need to add code to CreateKeywords()

d.Add(keywordOuterIt, keywordOuterIt);

Nicholas Mayne

I know this is old, but I am getting the exception

No applicable method 'Contains' exists in type 'Int16'

Any ideas on how to get around that?

Timothy Chi

Excellent!!!

Alan Macdonald

I can't get this to work. ParseAggregate is throwing the following exception on the last line to Expression.Call:

No generic method 'Contains' on type 'System.Linq.Enumerable' is compatible with the supplied type arguments and arguments. No type arguments should be provided if the method is non-generic.

Has anyone got this working with Entity Framework 6?

My calling code is

public IQueryable Search(IQueryable items)
{
return items.Where("@0.Contains(outerIt." + FieldName + ")", SelectedIds);

}

Alan Macdonald

My problem was being caused by the fact my column was Int64? but the array of IDs was Int64s. Changing the array to Int64? so the types matched for the nullability solved it.

Seems to work quite well. Cheers.

The comments to this entry are closed.

My Other Accounts

Links

Twitter Updates

    follow me on Twitter