Using DateTime.Add(TimeSpan) with LINQ - c#

I have to run a query like the one bellow. It is actually more complex, but here is the part that matters:
var results =
from b in _context.Bookings
where b.ScheduleDate.Add(b.StartTime) >= DateTime.UtcNow
select b;
But it gives the following error:
LINQ to Entities does not recognize the method 'System.DateTime.Add
method(System.TimeSpan)', and this method cannot be translated into a
store expression.
How can I work around this?
Thanks in advance.

Try using the SqlFunctions.DateAdd method in the System.Data.Objects.SqlClient namespace. Documentation here. That will convert into the SQL method DateAdd, documented here. You might also be interested in using DateDiff instead, documented here.
In general, look at SqlFunctions for "common language runtime (CLR) methods that call functions in the database in LINQ to Entities queries." LINQ to Entities cannot convert any method call into SQL, but the functions in that class will work.
Your other option is to execute the LINQ to Entities query (using ToList or something similar) and then perform the logic in memory.

SqlFunctions only works with Microsoft Sql Server.
In pure EF you can write:
DbFunctions.AddMilliseconds(x.Date, DbFunctions.DiffMilliseconds(TimeSpan.Zero, x.Time))
This works on all database adapters

Related

LINQ to Entities does not recognize the method 'System.Collections.Generic.IEnumerable`1

I am getting this error while using this IEquality comparer for intersection.
Can somebody identify where I am doing it wrong?
Pleas ask if you need more information.
When you write LINQ to Entities, you must remember that eventually all of your LINQ expression is translated to SQL. So for every method call you make in that expression, you should think if there's a reasonable way to translate it to SQL.
Having that in mind, you can see that:
SQL has no notion of .ToList(), which is probably the source of your current error. calls to .ToList() should be made at the end of the expression, as a way to "materialize" the query (i.e. make EF make the actual call to the database and return results).
Your database knows nothing about C# interfaces. You can't expect any implementation of IEqualityComparer to be translatable to SQL.
As #Dai has noted, you seem to be using too many joins. Make sure your model has the right navigation properties between entities, and use them.

Can a method chain be called LINQ?

Is it correct to call this code snippet LINQ (Language Integrated Query)?
var lstMyStrings = new List<string>();
lstMyStrings.Where(aX => string.IsNullOrEmpty(aX))
.Skip(3)
.ToList();
I am confused because System.Linq is mandatory for this code.
However, when I see questions and answer's like this: .NET LINQ query syntax vs method chain
, then they're talking explicit about a method chain and not LINQ.
LINQ can be written in two different ways.
One is by writing a query using LINQ declarative query syntax:
var query = from x in source
where condition
select x.Property
And the other is by using LINQ's extension methods:
var query = source.Where(condition).Select(x => x.Property);
Both queries are identical and will produce the same result (well, compiler error in this over-simplified example but it's the thought that counts :-))
The c# compiler translates the query into method calls.
This means that everything you write as a query can be also written using method chains. Please note, however, that the opposite is false - Some queries can only be written using Linq's extension methods.
For further reading, here's what Microsoft have to say about it.
Note the second paragraph starts with this:
Query syntax and method syntax are semantically identical, but many people find query syntax simpler and easier to read.
btw, if it was'nt already clear, the reason that System.Linq is mandatory for the method chaining syntax also is because the linq extension methods belongs to this namespace.

error - calculating percentage when using Linq

I have a Ling Query for calculate percentage.
var total = db.Schema_Details.Where(x => x.RID == sName).Select(x => new{
Rid = x.RID,
Amount = Convert.ToDouble(x.Lum_Sum_Amount),
Allocation = Convert.ToDouble(x.Allocation),
total = ((x.Allocation / 100) * x.Lum_Sum_Amount)}).ToList();
But exception occurred.
How can I solve this?
Since you use the identifier db, I assume db is a DbContext. This means that your linq statements will be executed in SQL on the database server side and not in your memory (SQL or something similar, depending on the type of DB your are using).
You can see this if you check the type of your statement in the debugger: is it an IQueryable or an IEnumerable? IQueryables are executed by the database server, IEnumerable are usually executed in your memory. Usually your database server can execute your linq statements faster and more efficient than you, so it is best to make sure your linq statements are IQueryable.
However, the disadvantage is, that you database server does not know any of your classes, functions, nor .NET. So in IQueryables you can only use fairly simple calculations.
If you really need to call some local functions somewhere halfway your linq statement, add AsEnumerable()to your statement:
var myLinqResult = db. ... // something IQueryable
.Where(item => ... ) // simple statement: still IQueryable
.Select(item => ...) // still simple, still IQueryable
// now you want to call one of your own functions:
.AsEnumerable()
.Select(item => myOwnLocalFunctions(item));
See stackoverflow: Difference between IQueryable and IEnumerable
The local function you want to perform is Convert.ToDouble. IQueryable does not know the Convert class, and thus can't perform your function as IQueryable. AsEnumerable will solve this problem.
However, in this case I would not advise to use AsEnumerable. When executing linq statements on a database try to avoid using local classes and function calls as much as possible. Instead of Convert.ToDoubleuse (double)x.Sum_Amount. Your linq-to-sql translator (or similar database language converter) will know how to translate this as IQueryable.
There are some calculations of which there are SQL equivalents, like DateTime calculations, or string reverse. It would be a shame if you had to do things like DateTime.AddDays(1) in local memory while there are perfect SQL equivalents for it. This would especially be a problem if you need to Join, Select or GroupBy after your local functions. Your database server can do these things far more efficiently than you. Luckily there are some IQueryable extension functions for them. They can be found in System.Data.Entity.DbFunctions

How to call a c# method when working with LINQ to NHibernate?

How to call a c# method when working with LINQ to NHibernate?
The below code fails:
List<UriTemplate> result1 = (from uriTemplate in this.SessionFactory.Session.Query<UriTemplate>()
where Regex.Match(uri, uriTemplate.UriTemplateValue).Success
select uriTemplate).ToList();
Not all methods are supported. Things like Contains and Substring might work. But you cannot expect that the underlying LINQ provider will be able to translate arbitrary C# methods to SQL. The underlying database might not even know what a regex is.
You will have to do the filtering on the client side, once you execute the query on the server:
List<UriTemplate> result1 = this
.SessionFactory
.Session
.Query<UriTemplate>()
.ToList()
.Where(uriTemplate => Regex.Match(uri, uriTemplate.UriTemplateValue).Success)
.ToList();
If your underlying database supports regex queries that will probably be done through some native function in which case you will need to invoke this native function if you want to do the filtering on the server.

Custom Linq functions for sql and entities

Is there a way to create functions for linq to sql that act different when used in linq to entities?
I do not whant to use a AsQueriable. I becouse I whant to do as much calculations on the sql server as possible.
example:
var UserIDs = Users.Select(x=> ConvertToString(x.UserID));
For linq to sql the code has to be:
public string ConvertToString(int id)
{
return SqlFunctions.StringConvert((double?)id);
}
For linq to entities the code has to be:
public string ConvertToString(int id)
{
return id.ToString();
}
You can use SqlFunctions in Entity Framework 4 and above. In your example, you do not have to do the conversion in the application layer.
http://blogs.microsoft.co.il/blogs/gilf/archive/2009/05/23/calling-database-functions-in-linq-to-entities-in-entity-framework-4.aspx
In Linq-to-Entites you won't be allowed to use the ConvertToString call in a query anyway, so this is a brave, but fruitless effort. The reason is that every statement in an L2E query must be an Expression that must be translatable to SQL by the query provider. And (of course) there is no built-in translation for any arbitrary method. L2E is very limited here. It is not even possible to use most native .Net methods like
Users.Select(x=> Convert.ToString(x.UserID)); // NotSupportedException
Linq-to-Sql is a bit more lenient in this. It will run the statement decently. But that does not help you, because you are looking for a common denominator. The bottleneck is L2E and it is a narrow bottleneck.

Categories

Resources