?
Solved

Linq to Entities does not translate Math.Exp

Posted on 2011-09-16
5
Medium Priority
?
765 Views
Last Modified: 2013-12-17
I am trying to run a Linq to Entities query using Silverlight and RIA against a SQL Server database and I receive the following error :

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

The lines causing the trouble are

            CalcChangeAmount = G.Sum(g => (double)g.PP.Quantity * (double)g.P0.Close * (double)(Math.Exp((double)(g.P1.PriceCummLogChange - g.P0.PriceCummLogChange)) - 1)),
            CalcAlphaAmount = G.Sum(g => (double)g.PP.Quantity * (double)g.P0.Close * (double)(Math.Exp((double)(g.P1.ActualCummLogAlpha - g.P0.ActualCummLogAlpha)) - 1))

in the attavched query.

Does anyone know why this is happening, and is there any sort of work-around?  Because of the size of the tables (and they are filtered on the silverlight side) it is not realistic to use ToList(0 or anything like that.

 
var PerformanceAnalysisIntermediate =
          from PP in ObjectContext.PortfolioPositions
          from TD in ObjectContext.DailyDates
          from FD in ObjectContext.DailyDates
          where PP.StartDate < TD.Date
          && (PP.EndDate >= FD.Date || PP.EndPrice == null)
          let StartDate = PP.StartDate < FD.Date ? FD.Date : PP.StartDate
          let EndDate = PP.EndDate > TD.Date || PP.EndDate == null ? TD.Date : PP.EndDate
          join P0 in ObjectContext.Prices
          on new { Date = ObjectContext.Prices.Where(p => p.EntityId == PP.EntityId && p.Close != null && p.ActualCummLogAlpha != null && p.Date <= StartDate).Max(p => p.Date), PP.EntityId } equals new { P0.Date, P0.EntityId }
          join P1 in ObjectContext.Prices
          on new { Date = ObjectContext.Prices.Where(p => p.EntityId == PP.EntityId && p.Close != null && p.ActualCummLogAlpha != null && p.Date <= EndDate).Max(p => p.Date), PP.EntityId } equals new { P1.Date, P1.EntityId }
          group new { PP, P0, P1, ToDate = TD.Date, FromDate = FD.Date } by new { PP.AccountEntityId, ToDate = TD.Date, FromDate = FD.Date, PP.EntityId } into G
          where G.Sum(g => g.P1.TCount - g.P0.TCount) > 0
          select new {
            G.Key.EntityId,
            G.Key.AccountEntityId,
            G.Key.FromDate,
            G.Key.ToDate,
            PCount = G.Count(),
            TCount = G.Max(g => g.P1.TCount) - G.Min(g => g.P0.TCount),
            StartDate = G.Min(g => g.PP.StartDate > g.FromDate ? g.PP.StartDate : g.P0.Date),
            EndDate = G.Max(g => g.PP.EndDate <= g.ToDate && g.PP.EndPrice != null ? g.PP.EndDate : g.P1.Date),
            AvgStartAmount = G.Sum(g => (double)g.PP.Quantity * (double?)(g.PP.StartDate > g.FromDate ? g.PP.StartPrice : g.P0.Close) * (double)(g.P1.TCount - g.P0.TCount)) / (double)G.Sum(g => g.P1.TCount - g.P0.TCount),
            AvgEndAmount = G.Sum(g => (double)g.PP.Quantity * (double?)(g.PP.EndDate <= g.ToDate && g.PP.EndPrice != null ? g.PP.EndPrice : g.P1.Close) * (double)(g.P1.TCount - g.P0.TCount)) / (double)G.Sum(g => g.P1.TCount - g.P0.TCount),
            AvgQuantity = G.Sum(g => (double)g.PP.Quantity * (double)(g.P1.TCount - g.P0.TCount)) / (double)G.Sum(g => g.P1.TCount - g.P0.TCount),
            AvgChangeAmount = G.Sum(g => (double)g.PP.Quantity * (double?)(g.PP.EndDate <= g.ToDate && g.PP.EndPrice != null ? g.PP.EndPrice : g.P1.Close) * (double)(g.P1.TCount - g.P0.TCount)) / (double)G.Sum(g => g.P1.TCount - g.P0.TCount)
                      - G.Sum(g => (double)g.PP.Quantity * (double?)(g.PP.StartDate > g.FromDate ? g.PP.StartPrice : g.P0.Close) * (double)(g.P1.TCount - g.P0.TCount)) / (double)G.Sum(g => g.P1.TCount - g.P0.TCount),
            CalcChangeAmount = G.Sum(g => (double)g.PP.Quantity * (double)g.P0.Close * (double)(Math.Exp((double)(g.P1.PriceCummLogChange - g.P0.PriceCummLogChange)) - 1)),
            CalcAlphaAmount = G.Sum(g => (double)g.PP.Quantity * (double)g.P0.Close * (double)(Math.Exp((double)(g.P1.ActualCummLogAlpha - g.P0.ActualCummLogAlpha)) - 1))
          };

Open in new window

0
Comment
Question by:eb8931
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
5 Comments
 
LVL 21

Accepted Solution

by:
Craig Wagner earned 1000 total points
ID: 36552115
LINQ-to-Entities must be able to translate everything contained in the query into something that will execute on the server (i.e. database) side. It can't translate Math.Exp to something that will execute within the database query so you get that exception. This article talks about which framework methods can be converted to server-side methods.

http://msdn.microsoft.com/en-us/library/bb738681.aspx

Under many circumstances you can just do the calculation outside the query and use the results. Unfortunately in your case the value you're performing the calculation on is part of the query.

Math.Exp raises e to the specified power. Math also has a static member called E. Also, given the link provided above, the Pow method is supported by LINQ-to-Entities. So, if you did something like the following it should work.


CalcChangeAmount = G.Sum(g => (double)g.PP.Quantity * (double)g.P0.Close * (double)(Math.Pow(Math.E, (double)(g.P1.PriceCummLogChange - g.P0.PriceCummLogChange)) - 1)),

Open in new window

0
 
LVL 63

Assisted Solution

by:Fernando Soto
Fernando Soto earned 1000 total points
ID: 36554587
Hi eb8931;

The Entity Framework has implemented many math functions which will translate to TSQL statements. These functions can be found at, SqlFunctions Class. To modify your statements to work add the using statement and change the word Math to SqlFunctions as shown in the code snippet below.

using System.Data.Objects.SqlClient;

CalcChangeAmount = G.Sum(g => (double)g.PP.Quantity * (double)g.P0.Close * (double)(SqlFunctions.Exp((double)(g.P1.PriceCummLogChange - g.P0.PriceCummLogChange)) - 1)),

Open in new window


Fernando
0
 
LVL 63

Expert Comment

by:Fernando Soto
ID: 36554590
0
 

Author Closing Comment

by:eb8931
ID: 36559175
Thanks  guys for your help.
0
 
LVL 63

Expert Comment

by:Fernando Soto
ID: 36562109

Not a problem, always glad to help.
0

Featured Post

Free Backup Tool for VMware and Hyper-V

Restore full virtual machine or individual guest files from 19 common file systems directly from the backup file. Schedule VM backups with PowerShell scripts. Set desired time, lean back and let the script to notify you via email upon completion.  

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A long time ago (May 2011), I have written an article showing you how to create a DLL using Visual Studio 2005 to be hosted in SQL Server 2005. That was valid at that time and it is still valid if you are still using these versions. You can still re…
A Stored Procedure in Microsoft SQL Server is a powerful feature that it can be used to execute the Data Manipulation Language (DML) or Data Definition Language (DDL). Depending on business requirements, a single Stored Procedure can return differe…
Using examples as well as descriptions, and references to Books Online, show the documentation available for datatypes, explain the available data types and show how data can be passed into and out of variables.
Viewers will learn how the fundamental information of how to create a table.
Suggested Courses

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question