Linq to Entities Does Not Recognize the Method 'Double Parse(System.String)' Method, and This Method Cannot Be Translated into a Store Expression

LINQ to Entities does not recognize the method 'Int32 Parse(System.String)' method when attempting to parse a column for inequality comparisons

First, I would highly recommend to check your database design, whether there is a really good reason for ID to be a string. I would consider changing the ID DB type to int and you will get rid of this problem with converting.

The error you get means, that EF does not know how to convert the method Int32.Parse() to SQL.
Basically you have two options how to deal with that:

Do the comparison outside the linq to entities:

var myVar= Entity.SetName.AsEnumerable()
.Where(p => int.Parse(p.ID) >= start &&
int.Parse(p.ID) <= end);

But this is not recommended, because you are reading whole result set from DB, before applying the where condition.

Or make custom model defined function as described in this post on SO:

Convert String to Int in EF 4.0
or
Entity Framework: Where do I extend the CSDL/MSL?

LINQ to Entities does not recognize the method 'Int32 Parse(System.String)' method, and this method cannot be translated into a store expression

in Linq to Entity, you should use the methods in your query which is supported by your provider to convert them to expression tree to run on your Data Base side.

all providers must support some methods by default called Canonical Functions (Read More Here), and also you can define your user defined function and stored procedure as edm functions to use in linq query (Read More Here) and (Here).

in addition you can use methods which is supported by providers and can be converted to expression tree which are in EntityFunctions and SqlFunctions.

and finally about your question, you can convert UserID and ClassID before your query, like this:

var UID = int.Parse(UserID);
var CID = int.Parse(ClassID);
var record = context.enrollments.SingleOrDefault
(row => row.userId == UID && row.classId == CID);

LINQ to Entities does not recognize the method 'Double ToDouble(System.String)' method, and this method cannot be translated into a store expression

You will need to use AsEnumerable so as to work with the records in memory after it has been returned from the database. Then you will be able to use Convert.ToDouble

var ObligationRequestDetailsTotalCostByOoe = (from p in db.iBudget_ObligationRequestDetails
where p.ooe_general_id != null && p.is_approved == 1
group p by p.ooe_general_id into g
select g) // <-- db call
.AsEnumerable() //<-- memory call
.Select(g => new {
id = g.Key,
amount = g.Sum(p => Convert.ToDouble(p.amount))
})
.ToList();

LINQ to Entities does not recognize the method 'Double Parse(System.String)' cannot be translated into a store expression C# asp.net

Actually the following solved the problem and provided the required results:

 var datasource = (from x in db.Departments orderby x.DepartmentNumber select x).ToList().OrderBy(Department => Convert.ToDouble(Department.DepartmentNumber, System.Globalization.CultureInfo.InvariantCulture));

Sample Image

LINQ To Entity - LINQ to Entities does not recognize the method 'Double Parse(System.String)' method

Having a double value in SQL server as string is questionable. Proably then you might also want to compare it as string without parsing at all.
Assuming you would like you to do with parsing, double.Parse() doesn't have a corresponding conversion in EF you could indirectly do it at the client side:

var order = (from Order in entities.Orders
where Order.BTC_Address == "123" select Order)
.AsEnumerable()
.Where(o => double.Parse(o.BTC_Amount) == amount_dbl)
.FirstOrDefault();

From the point forward you have AsEnumerable(), it is client side.

EDIT: And this is the method way:

var order = entities.Orders
.Where(Order => Order.BTC_Address == "123")
.AsEnumerable()
.Where(o => double.Parse(o.BTC_Amount) == amount_dbl)
.FirstOrDefault();

PS: I would directly write the double value instead of parsing from a string as in your example.

PS2: Also don't forget, with a double you are unlikely to get equal values. In SQL server and C# side a decimal is a more appropriate type to use.

LINQ to Entities does not recognize the method 'Double Parse(System.String)' method, and this method cannot be translated into a store expression

The problem here is that your query is being translated into SQL and run on the database, and Entity Framework doesn't know how to translate Double.Parse into valid SQL code. However, you can define a custom method to do the parsing, and tell Entity Framework how to translate that method to SQL. Here's how it goes:

Define the translation

Open up your *.edmx file in a text editor, and look for the <edmx:ConceptualModels> tag. Under that you should see a <Schema Namespace="YourModel" ...> tag. Inside the Schema tag, add the following:

    <Function Name="ParseDouble" ReturnType="Edm.Double"> 
<Parameter Name="stringvalue" Type="Edm.String" />
<DefiningExpression>
cast(stringvalue as Edm.Double)
</DefiningExpression>
</Function>

This defines the Enity-SQL code that your custom ParseDouble function is going to be translated into.

Create a method to be translated

Now we need to define a matching function in code that you can put in your LINQ statement. Your EDMX file is used to generate a partial class that inherits from ObjectContext. Since it's a partial class, you can add your own methods to it without touching the generated code - just make sure the class names match.

using System.Data.Objects.DataClasses;

public partial class YourObjectContext
{
/// <summary>
/// This method exists for use in LINQ queries,
/// as a stub that will be converted to a SQL CAST statement.
/// </summary>
[EdmFunction("YourModel", "ParseDouble")]
public static double ParseDouble(string stringvalue)
{
return Double.Parse(stringvalue);
}
}

Now you can go back to your LINQ statement, and replace any instances of Double.Parse with YourObjectContext.ParseDouble. Since this is an actual method that actually calls Double.Parse, it will work on LINQ to Objects calls, and since it is also defined in the EDMX file, it can be translated into SQL by LINQ to Entities as well.

But wait, you're not done yet!

I noticed that your LINQ statement also includes a call to Math.Round. I don't know off the top of my head if Entity Framework includes a translation for that method, but if it doesn't, you'll get the same error for that method after you fix the one for Double.Parse. Fortunately, the solution for that case is almost exactly the same, except the function defined in the EDMX file would look something like this:

    <Function Name="Round" ReturnType="Edm.Double"> 
<Parameter Name="input" Type="Edm.Double" />
<DefiningExpression>
Round(input)
</DefiningExpression>
</Function>

You can use this list of EDM Canonical Functions to see what's valid to put inside the <DefiningExpression> tags.

LINQ to Entities does not recognize the method 'Int32 Int32(System.String)' method, and this method cannot be translated into a store expression


public IEnumerable<CourseNames> GetCourseName()
{
var courses = from o in entities.UniversityCourses
select new { o.CourseID, o.CourseName };

return courses.ToList() // now we have in-memory query
.Select(c => new CourseNames()
{
CourseID = Convert.ToInt32(c.CourseID), // OK
CourseName = c.CourseName
});
}

LINQ to Entities does not recognize the method 'Int32 ToInt32(System.Object)' method, and this method cannot be translated into a store expression

Instead of this:

Select(a => Convert.ToInt32(a.RoleId))

Do this:

Select(a => a.RoleId.Value)

The reason is in the error description; when you are doing these queries through IQueryable, the methods being used within the selector have to be something that can be translated into a SQL query or function. In this case Convert.ToInt32() is not such a method. For int fields with null allowed, using the .NET .Value property does work, though.

Note that this would not work if your RoldId is null, however. You'll get an InvalidOperationException. You might want to return a set value instead if the backing field is null:

Select(a => a.RoleId.HasValue ? a.RoleId.Value : int.MinValue)

This will return the value if there is one, and int.MinValue if not.



Related Topics



Leave a reply



Submit