Entity Framework Min Aggregate crashes on website but runs on console app? - entity-framework

I have this Linq To Entites query below. When I execute this query from a Console Application, it produces SQL and executes perfectly.
But when I execute it from a web application, I get an error message that says the Min() function is not recognized by Linq To Entites and it cannot be translated to a store expression.
It is EXACTLY the same query. Both project have the same settings (concerning EF 6) in their config files, and they reference the same assemblies.
from ce in db.CustomEvents
where ce.fld_start > DateTime.Now
group ce by ce.fld_ownerId into g
select new
{
fld_ownerId = g.Key,
next_appointement_date = g.Min(i => i.fld_start)
}
It seems this happens only when the Min aggregate is on DateTime property. I hadn't this issue when I had Min on decimals, for instance.
The error message I get when I execute this in the web site is this
LINQ to Entities does not recognize the method 'System.Nullable`1[System.DateTime]
Min[CustomEvent](System.Collections.Generic.IEnumerable`1[CustomEvent],
System.Func`2[CustomEvent,System.Nullable`1[System.DateTime]])'
method, and this method cannot be translated into a store expression.
But when I execute it from the Console app, it successfully generates the SQL statement below
SELECT
1 AS [C1],
[GroupBy1].[K1] AS [fld_ownerId],
[GroupBy1].[A1] AS [C2]
FROM ( SELECT
[Extent1].[fld_ownerId] AS [K1],
MIN([Extent1].[fld_start]) AS [A1]
FROM [dbo].[mtbl_CustomEvent] AS [Extent1]
WHERE [Extent1].[fld_start] > (SysDateTime())
GROUP BY [Extent1].[fld_ownerId]
) AS [GroupBy1]
Does anyone have a clue on what is happening?? Why the same query generates SQL when run in the console app, but fails with an exception when run in the web site??
UPDATE:
It seems that the problem was an ambiguity between two different implementations of Min<T>(this IEnumerable<T>) (.net's implementation, and our own implementation). Removing the "using OurLibrary;" namespace from the file fixed the problem.

After vittore's suggestion to use extension methods syntax we found that the problem was that in the web project we referenced one of our libraries that included an implementation of Min<T>(this IEnumerable<T>), and we also had the using OurLibrary.Namespace; directive in the file where the linq query was.
When we used the linq syntax, the compiler picked our implementation of Min for the query and did not throw any errors. Then, at runtime, the LINQ to Entities framework crashed because it could not recognise our implementation of Min.
from ce in db.CustomEvents
where ce.fld_start > DateTime.Now
group ce.fld_start by ce.fld_ownerId into g
select new
{
fld_ownerId = g.Key,
next_appointement_date = g.Min()
}
Here there was no compiler error.
But when we used the extension method syntax, the compiler stopped with an ambiguity error, and that's how we identified the problem.
db.CustomEvents
.Where(ce => ce.fld_start > DateTime.Now)
.GroupBy(ce => ce.fld_ownerId, ce => ce.fld_start)
.Select(g => new { g.Key, next_appointement_date = g.Min() })
Here the compiler threw an error of ambiguous call to .Min
It's weird that the compiler does not recognise the ambiguity in the Linq syntax. After all, linq is only syntactic sugar.

Related

Slick 2.1.x Invalid query because of `

I am working on legacy code which was written in slick 2.1 (can't upgrade right now).
val query = foo.filter(x => x.d >= input._1).filter(x => x.d < input._2)
println(query.selectStatement)
query.list
I can see that this generate the query
select x2.`a`, x2.`b`, x2.`c`, x2.`d` from `foo` x2 where (x2.`d` >= {ts '2016-07-30 00:00:00.0'}) and (x2.`d` < {ts '2016-07-30 23:23:59.0'})
when this executes, it gives an error java.sql.SQLSyntaxErrorException: ORA-00911: invalid character
When I copy paste this printed query into Oracle query editor it gives the same error there. However if I remove all the ```s then it works. Why is slick 2.1.x generate bad query? is there anyway to tell it to stop generating "`"s
I found the answer. I had imported the wrong driver. I had imported MySQLDriver and was trying to execute the code against Oracle.
Importing the right OracleDriver (via slick-extensions) generated the right query.

How to run dynamic SQL query in Entity Framework 7 that auto-maps to Entities (SqlQuery<T>)?

I have an existing app that I am trying to upgrade from MVC5/EF6 to MVC6/EF7. We dynamically create some of our SQL tables, and as a result, have made use of the
System.Data.Entity.Database.SqlQuery
method to automatically map to entities that we use throughout our application.
This method seems to have gone away (i.e. not part of
Microsoft.Data.Entity.Infrastructure.Database ) in EF7 (or is not yet implemented). Are there plans to re-implement this method in EF7 or is there another way to accomplish this? Our project is kind of dead in the water until we figure this out.
Edited on May 20, 2015
I've been trying to make this work with FromSql, since that's what's available in Beta4, but no matter what combination of concatenated string, parameters I try, I keep getting different versions of an "Incorrect Syntax near #xxxvariable" message.
var results = Set<AssessmentResult>().FromSql("dbo.GetAssessmentResults #FieldA='Data1', #FieldB='Data2', #UserId = 2303");
var results2 = Set<AssessmentResult>().FromSql("dbo.GetAssessmentResults #FieldA= {0}", intData);
Both of these calls result in
"Incorrect syntax near '#FieldA'"
Any ideas?
We recently introduced the .FromSql() extension method on DbSet. It has the added benefit that you can continue composing LINQ on top of it.
var customers = db.Customers
.FromSql("SELECT * FROM Customer")
.Where(c => c.Name.StartsWith("A"));

Linq To Entities: "Sequence contains no elements" with Count()

In our appliction we have a piece of code with some Linq-queries (EF) that sometimes throws an exception.
This has only happened to the end user, and we are not able to reproduce it so far.
From the logfile we got the following stacktrace for the exception:
System.InvalidOperationException: Sequence contains no elements
at System.Linq.Enumerable.Single[TSource](IEnumerable1 source)
at System.Data.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__3[TResult](IEnumerable1 sequence)
at System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable1 query, Expression queryRoot)
at System.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[S](Expression expression)
at System.Linq.Queryable.Count[TSource](IQueryable1 source)
at MT3.uctXGrid.LoadLayout(String strUniqueID, Boolean rethrowException, List`1 visibleColumns)
In the method LoadLayout there are only 2 instances of Count(), and they are just operating on standard IQueryables which interrogate an entity type based on one integer field and select all fields (no aggregations or anything).
ex:
from p in cxt.genData where datId = ID
In the stacktrace, it seems like internally .Single() is being used which could throw an exception if there are no records.
But why is it using single if we are just calling .Count() ?
How can a query like
(from p in cxt.genData where datId = ID).Count()
throw a "sequence contains no elements" exception?
We have had other strange problems with queries as well, I'm starting to wonder if there are any issues with our version of EF maybe.
We are still on 4.0 at the moment. (Standard version which came with VS2010).
Has anyone got an idea what could be going on here?
Update:
Here are the Linq-to-Entities queries we actually use
Dim qryLastLayout = From t In oContext.genGridLayouts Where t.layID = intCurrentLayoutID
If Not IsNothing(qryLastLayout) AndAlso qryLastLayout.Count <> 0 Then
Dim qryPrintSettings = From p In oContext.genPrintSettings Where p.prtDefault = True
If Not IsNothing(qryPrintSettings) AndAlso qryPrintSettings.Count <> 0 Then
Have you tried using the .Any() method?
if(cxt.genData.Any(x => x.datId == ID))
{
// do something here
}
One thing to be aware of wrt Linq to Entities is that the semantics of Count() are not those of .NET but those of the underlying datasource (somewhat undermining the whole language-integration aspect, but oh well...). I don't think this can cause issues like yours, but you never know.
MSDN link with more details: http://msdn.microsoft.com/en-us/library/vstudio/bb738551.aspx#sectionSection5

Subsonic error: The ORDER BY clause is invalid...., unless TOP or FOR XML is also specified

I'm using Subsonic 2.1 and I'm having an error with the next query:
SqlQuery queryResTitle = new Select(
new Aggregate(ResTitle.ResourceTitleIDColumn, "ResourceTitleID", AggregateFunction.GroupBy),
new Aggregate(ResTitle.ResourceTitleColumn, "ResourceTitle", AggregateFunction.GroupBy),
new Aggregate(VenVendor.TitleColumn, "Title", AggregateFunction.GroupBy),
new Aggregate(ResTitleStatus.StatusColumn, "Status", AggregateFunction.GroupBy))
.From(Tables.ResTitleOngoing)
.InnerJoin(ResTitleStatus.ResourceTitleIDColumn, ResTitle.ResourceTitleIDColumn)
.LeftOuterJoin(VenVendor.VendorIDColumn, ResTitle.VendorIDColumn);
I'm getting the error:
"The ORDER BY clause is invalid in
views, inline functions, derived
tables, subqueries, and common table
expressions, unless TOP or FOR XML is
also specified"
I also added .Top("1") but I still got the same error.
You should debug the generated query that SubSonic returns:
var queryString = queryResTitle.BuildSqlStatement();
and execute it in your favorite database administration tool.
Maybe you can figure out what's going wrong.

Versant OQL Statement with an Arithmetic operator

I'm working on a c# project that use a Versant Object Database back end and I'm trying to build a query that contains an arithmetic operator. The documentation states that it is supported but lack any example.
I'm trying to build something like this:
SELECT * FROM _orderItemObject WHERE _qtyOrdered - _qtySent > 0
If I try this statement in the Object Inspector I get a synthax error near the '-'.
Anyone has an example of a working VQL with that kind of statement?
Thanks
I am not sure that the Object Inspector will know the syntax for the arithmtic expression. However, in your code you should be referring to the fully qualified class. Then the syntax you are using should be perfectly fine.
Query query = new Query( session,
"select * from com.yourCompany.yourClass where _qtyOrdered - _qtySent > 0 ");
QueryResult result = query.execute();
I just tried this out on one of my classes and it worked fine.
Cheers,
-Robert
With C# and OQL you have to make sure you select the proper class extent. This is done by adding the "Extent" suffix to the class name. For example, in my Pet class I would identify all the pets with "PetExtent" in the OQL string.
Class members are accessed in the predicate by defining a local moniker, p in the code below. Any arithmetic expressions will be evaluated by the query engine.
string query="SELECT * FROM PetExtent AS p WHERE p.Name = \"Ferris\" AND (p.age + 5) > 4";
IQueryResult result = scope.GetOqlQuery(query).Execute();
foreach (object o in result)
Out(o.ToString());
The best way to test OQL with Versant's C# binding is to use the OQL Query Browser integrated into Visual Studio. Look under the Versant Menu drop down in Visual Studio.
Best Regards,
Derek