Reputation: 6577
I am trying to run a simple custom query that is returned into a custom object, however, I keep running into an error and I have no idea what is wrong. The query runs just fine in SQL Server Management Studio.
public class MyClass
{
public Nullable<int> EligibleCredits { get; set;}
public Nullable<int> ReadyForSubmissionCredits { get; set; }
public Nullable<int> RedeemedCredits { get; set; }
}
Main Method:
var query = @"SELECT
(select count(*) from MyTable where UserId = @userId and [Status] = 0 and Year(EarnDate) >= (select Year(getdate()) -@years)) as EligibleCredits,
(select count(*) from MyTable where UserId = @userId and [Status] = 1 and Year(EarnDate) >= (select Year(getdate()) -@years)) as ReadyForSubmissionCredits,
(select count(*) from MyTable where UserId = @userId and [Status] = 2 and Year(EarnDate) >= (select Year(getdate()) -@years)) as RedeemedCredits";
var objectQuery = new ObjectQuery<MyClass>(query, ((IObjectContextAdapter)this).ObjectContext);
objectQuery.Parameters.Add(new ObjectParameter("userId", userId));
objectQuery.Parameters.Add(new ObjectParameter("years", years));
return objectQuery.FirstOrDefault();
The error that I get is:
The query syntax is not valid. Near term '*', line 2, column 39.
This query runs fine in SQL Server Management Studio.
Also, according to this article, I'm doing it correctly: https://msdn.microsoft.com/en-us/library/bb738521(v=vs.100).aspx
Upvotes: 4
Views: 2301
Reputation: 356
ExecuteStoreQuery worked for me, for the same error. Sample below:
IList<MyClass> contactList =
(((IObjectContextAdapter) model).ObjectContext.ExecuteStoreQuery<MyClass>(strString))
.ToList<MyClass>();
Upvotes: 0
Reputation: 18379
This is a bug in the EntityFramework query parser. All I can do, is to provide you with a workaround (which BTW, may even run faster):
var query = @"SELECT
ISNULL(SUM(CASE WHEN [Status] = 0 THEN 1 ELSE 0 END),0) as EligibleCredits,
ISNULL(SUM(CASE WHEN [Status] = 1 THEN 1 ELSE 0 END),0) as ReadyForSubmissionCredits,
ISNULL(SUM(CASE WHEN [Status] = 2 THEN 1 ELSE 0 END),0) as RedeemedCredits
FROM MyTable
WHERE UserId = @userId
AND Year(EarnDate) >= Year(getdate()) - @years";
var objectQuery = new ObjectQuery<MyClass>(query, ((IObjectContextAdapter)this).ObjectContext);
objectQuery.Parameters.Add(new ObjectParameter("userId", userId));
objectQuery.Parameters.Add(new ObjectParameter("years", years));
return objectQuery.FirstOrDefault();
Note that if this
is an instance of DbContext
, you can simplify your code as follows:
var query = @"SELECT
ISNULL(SUM(CASE WHEN [Status] = 0 THEN 1 ELSE 0 END),0) as EligibleCredits,
ISNULL(SUM(CASE WHEN [Status] = 1 THEN 1 ELSE 0 END),0) as ReadyForSubmissionCredits,
ISNULL(SUM(CASE WHEN [Status] = 2 THEN 1 ELSE 0 END),0) as RedeemedCredits
FROM MyTable
WHERE UserId = @p0 -- <== NOTE THE PARAM NAME HERE AND BELOW
AND Year(EarnDate) >= Year(getdate()) - @p1";
return new this.Database.SqlQuery<MyClass>(query, userId, years).FirstOrDefault();
This last approach also works with your original query.
Upvotes: 2