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
Solved

Linq to Entities does not translate Math.Exp

Posted on 2011-09-16
5
757 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
  • 3
5 Comments
 
LVL 21

Accepted Solution

by:
Craig Wagner earned 250 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 250 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

Microsoft Certification Exam 74-409

Veeam® is happy to provide the Microsoft community with a study guide prepared by MVP and MCT, Orin Thomas. This guide will take you through each of the exam objectives, helping you to prepare for and pass the examination.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
SQl Query to find x consecutive Nbrs in a Table 30 94
SSRS - Date Report Options 2 26
Where is this file? 3 25
SQL Availablity Groups List 2 6
Let's review the features of new SQL Server 2012 (Denali CTP3). It listed as below: PERCENT_RANK(): PERCENT_RANK() function will returns the percentage value of rank of the values among its group. PERCENT_RANK() function value always in be…
Slowly Changing Dimension Transformation component in data task flow is very useful for us to manage and control how data changes in SSIS.
Via a live example, show how to backup a database, simulate a failure backup the tail of the database transaction log and perform the restore.
Viewers will learn how to use the SELECT statement in SQL to return specific rows and columns, with various degrees of sorting and limits in place.

792 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