Get property by name - linq

Can i somehow access property by it's name (represented by string) within lambda expression in Linq-to-Sql?
Say, something like
collection.Where(x => Get_Property(x, property_name)==property_value)
Actually, my problem is a code where Get_Property was implemented with reflection so that Linq2Obj was used instead of Linq2Sql and all work was performed by app instead of sql server.

Try DynamicLINQ. It creates lambda expressions from strings, and those expressions are used by the ORM.

No, you can't do this, because there is only set of methods which could be converted into SQL. Your custom methods or reflection API is not part of that set.
You can use Entity SQL to compose your query as a string.

Related

Define business methods usable by linq to entity and linq to objects

I use in my project a lot of LINQ queries and business methods.
To allow these business method to be used from an Iqueryable :
I defined UDF functions in SQL Server (with the needed parameters)
Add this UDF to the EDMX model of the application
And make a gateway between UDF and LinQ with a method like this in a
partial class who inherits from the dbcontext :
[EdmFunction("MyProject.Store", "GetTaxesOfProduct")]
public static Decimal GetTaxesOfProduct(Decimal amount, Int32 TaxMethod)
{
throw new NotSupportedException("Not direct access possible, use with E-SQL or LINQ");
}
This works perfectly for IQueryable.
But the problem is that, to use this method from a simple object (not linked to a database record), i need to make something creepy like this :
var query = from foo in context.JustATable select context.GetTaxesOfProduct(15.55, 3);
And recently i came across this http://blogs.msdn.com/b/charlie/archive/2008/01/31/expression-tree-basics.aspx who explain how, with expression, you can make a method who is usable from C# objects and IQueryable
So, with expression, is it possible to make business methods like my method but without the use of UDF and just expressions ?
Thank you by advance !
It depends on the content of your UDF. Expression can work only with entities defined in your model and use only operations provided by Entity Framework provider for your database. So if you use any complex SQL statement with not supported equivalent for LINQ or non mapped features inside your UDF it will not work.

Expression Lambda - retriveing Filed

is it possibile executing through Expression class a Select (projection) passing data field as string in order to achieve a strongly typed collection?
That' because I'm working with Linq to Entities and I would be able to making some retrive by grabbing wpf grid column name.
IS it exist something like Expression.Lamba.Select("field1, field2") which return a List..?
You could create a method that would call Select() with an expression that creates a Tuple (or possibly something else) from properties in your entity and let EF handle the rest.
The problem is, the only way you could treat the result of such method in a strongly-typed way would be if you knew the exact type it should return at compile-type, which it seems you don't.
The best you can do is to treat the result as a non-generic IEnumerable or alternatively try to use dynamic.

Workarounds for using custom methods/extension methods in LINQ to Entities

I have defined a GenericRepository class which does the db interaction.
protected GenericRepository rep = new GenericRepository();
And in my BLL classes, I can query the db like:
public List<Album> GetVisibleAlbums(int accessLevel)
{
return rep.Find<Album>(a => a.AccessLevel.BinaryAnd(accessLevel)).ToList();
}
BinaryAnd is an extension method which checks two int values bit by bit. e.g. AccessLevel=5 => AccessLevel.BinaryAnd(5) and AccessLevel.binaryAnd(1) both return true.
However I cannot use this extension method in my LINQ queries. I get a runtime error as follows:
LINQ to Entities does not recognize the method 'Boolean BinaryAnd(System.Object, System.Object)' method, and this method cannot be translated into a store expression.
Also tried changing it to a custom method but no luck. What are the workarounds?
Should I get all the albums and then iterate them through a foreach loop and pick those which match the AccessLevels?
I realize this already has an accepted answer, I just thought I'd post this in case someone wanted to try writing a LINQ expression interceptor.
So... here is what I did to make translatable custom extension methods: Code Sample
I don't believe this to be a finished solution, but it should hopefully provide a good starting point for anyone brave enough to see it through to completion.
You can only use the core extension methods and CLR methods defined for your EF provider when using Entity Framework and queries on IQueryable<T>. This is because the query is translated directly to SQL code and run on the server.
You can stream the entire collection (using .ToEnumerable()) then query this locally, or convert this to a method that is translatable directly to SQL by your provider.
That being said, basic bitwise operations are supported:
The bitwise AND, OR, NOT, and XOR operators are also mapped to canonical functions when the operand is a numeric type.
So, if you rewrite this to not use a method, and just do the bitwise operation on the value directly, it should work as needed. Try something like the following:
public List<Album> GetVisibleAlbums(int accessLevel)
{
return rep.Find<Album>(a => (a.AccessLevel & accessLevel > 0)).ToList();
}
(I'm not sure exactly how your current extension method works - the above would check to see if any of the flags come back true, which seems to match your statement...)
There are ways to change the linq query just before EF translates it to SQL, at that moment you'd have to translate your ''foreign'' method into a construct translatable by EF.
See an previous question of mine How to wrap Entity Framework to intercept the LINQ expression just before execution? and mine EFWrappableFields extension which does just this for wrapped fields.

Linq to NHibernate extensibility for custom string query operations?

I would like to be able to use custom string querying within my NHibernate Linq expressions. Let's say for example (and this is just an example) I would like to be able to select entities containing a property which is an anagram of a particular string:
var myEntities = EntityRepository.AllEntities.Where(x => x.Description.IsAnagramOf('hits');
I imagine the steps involved in this process would be:
Define a SQL Server UDF to determine
whether two strings are anagrams.
Define an extension method called
IsAnagramOf() for the String
class.
(And this is the tricky one). Modify
Linq to NHibernate's
component for parsing expression
trees so that it converts calls to
the extension method into the
appropriate SQL UDF call.
My question is this. Does Linq to NHibernate contain some kind of extensibility model enabling me to 'slot in' my own custom string operations, or would I literally have to modify the existing source code to add in my shiznit to the expression tree parsing component?
The extensibility is built in NH 3.0 (final release next month).
You can see a full working example at http://fabiomaulo.blogspot.com/2010/07/nhibernate-linq-provider-extension.html

Converting Hibernate linq query to HQL

I understand that a IQueryable cannot be serialized. That means that queries can not be serialized, sent to a webservice, deserialized, queried and then sent back.
I was wondering if it is possible to convert a hibernate linq query to hql to be sent over the wire.
Is there another route I am missing?
I think I've seen ADO.NET Data Services as advertised to work with NHibernate:
http://wildermuth.com/2008/07/20/Silverlight_2_NHibernate_LINQ_==_Sweet
http://ayende.com/Blog/archive/2008/07/21/ADO.Net-Data-Services-with-NHibernate.aspx
This is an old post, and not sure how maintained this feature is, but its worth a shot.
I have a suggestion to you. Do not try to serialize query. Rather provide your user with an ability to compose arbitrary LINQ expression. Then send the expression over the wire (there is a gotcha here, since expressions are not serializable) to your server.
I have recently submitted to NHibernate.Linq project a change to their NHibernateExtensions class - a new ISession extension method List, which accepts an expression and fills the given list with the respective data, much like ICriteria.List method. The change was accepted (see here) so downloading the recent version of NHibernate.Linq should contain this method.
Anyway, you can find the details of this approach here.

Resources