LINQ expression works in LinqPad but not C# Silverlight Application
I have been working with a Linq query in a Silverlight application which returns only the row of a table which contains the max value of the field OptionARMRunId (identity). When executed in LinqPad, the query runs fine and returns the correct row. However, when used in my Silverlight application, the application never moves past the loading screen (while the status percentage goes to 100%, the blue circle continues to go around ad nauseam) and I receive an error in the browser. I have included the original Linq statement, the statement as it appears in my query, and the ie error below.
Linq statement (works correctly):
from OptionARMProjection in OptionARMProjections.Where(row => row.OptionARMRunId == OptionARMProjections.Max(r => r.OptionARMRunId))
select OptionARMProjection
Linq statement in C# class (causes error when silverlight application is run):
crocodileEntities proxy = new crocodileEntities(new Uri("CrocodileDbDataService.svc", UriKind.Relative));
var ProjectionsQuery = from OptionARMProjections in proxy.OptionARMProjections.Where(row => row.OptionARMRunId == proxy.OptionARMProjections.Max(r => r.OptionARMRunId))
select OptionARMProjections;
Error received in ie8:
Webpage error details
User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; Zune 4.0; OfficeLiveConnector.1.4; OfficeLivePatch.1.3; .NET4.0C; .NET4.0E) Timestamp: Wed, 20 Jan 2010 03:06:13 UTC
Message: Unhandled Error in Silverlight 2 Application The method 'Max' is not supported. at System.Data.Services.Client.ResourceBinder.VisitMethodC开发者_运维知识库all(MethodCallExpression mce) at System.Data.Services.Client.ExpressionVisitor.Visit(Expression exp) at System.Data.Services.Client.DataServiceExpressionVisitor.Visit(Expression exp) at System.Data.Services.Client.ExpressionVisitor.VisitBinary(BinaryExpression b) at System.Data.Services.Client.ResourceBinder.VisitBinary(BinaryExpression b) at System.Data.Services.Client.ExpressionVisitor.Visit(Expression exp) at System.Data.Services.Client.DataServiceExpressionVisitor.Visit(Expression exp) at System.Data.Services.Client.ExpressionVisitor.VisitLambda(LambdaExpression lambda) at System.Data.Services.Client.ExpressionVisitor.Visit(Expression exp) at System.Data.Services.Client.DataServiceExpressionVisitor.Visit(Expression exp) at System.Data.Services.Client.ExpressionVisitor.VisitUnary(UnaryExpression u) at System.Data.Services.Client.ExpressionVisitor.Visit(Expression exp) at System.Data.Services.Client.DataServiceExpressionVisitor.Visit(Expression exp) at System.Data.Services.Client.ExpressionVisitor.VisitExpressionList(ReadOnlyCollection
at OptionARMChart.App.Application_Startup(Object sender, StartupEventArgs e) at MS.Internal.CoreInvokeHandler.InvokeEventHandler(Int32 typeIndex, Delegate handlerDelegate, Object sender, Object args) at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, String eventName) Line: 1 Char: 1 Code: 0 URI: http://localhost:5004/optionarmcharttestpage.aspx1 original) at System.Data.Services.Client.ExpressionVisitor.VisitMethodCall(MethodCallExpression m) at System.Data.Services.Client.ResourceBinder.VisitMethodCall(MethodCallExpression mce) at System.Data.Services.Client.ExpressionVisitor.Visit(Expression exp) at System.Data.Services.Client.DataServiceExpressionVisitor.Visit(Expression exp) at System.Data.Services.Client.ResourceBinder.AnalyzeProjection(MethodCallExpression mce, Boolean matchMembers, Expression& e) at System.Data.Services.Client.ResourceBinder.VisitMethodCall(MethodCallExpression mce) at System.Data.Services.Client.ExpressionVisitor.Visit(Expression exp) at System.Data.Services.Client.DataServiceExpressionVisitor.Visit(Expression exp) at System.Data.Services.Client.ResourceBinder.Bind(Expression e) at System.Data.Services.Client.DataServiceQueryProvider.Translate(Expression e) at System.Data.Services.Client.DataServiceQuery
1.get_QueryComponents() at System.Data.Services.Client.DataServiceRequest.CreateResult(Object source, DataServiceContext context, AsyncCallback callback, Object state) at System.Data.Services.Client.DataServiceQuery`1.BeginExecute(AsyncCallback callback, Object state) at OptionARMChart.OptionARMUniverse.GetOptionArmProjectionsASync() at OptionARMChart.MainPage..ctor()
.Max() isn't supported, a workaround would be to do an reverse order and take the first:
var ProjectionsQuery = proxy.OptionARMProjections
.Where(row => row.OptionARMRunId == proxy.OptionARMProjections
.OrderByDescending(r => r.OptionARMRunId))
.Take(1);
Correction: Seems it is supported in Silverlight 3+, but it's given me the same trouble more than once, so maybe someone can add some more details as to why.
The URI syntax used by Data Services does not support all functions that are supported by LINQ to Objects or LINQ to SQL. I assume when you are querying this in LINQPad, you are doing a LINQ to SQL query which is why it could work there. However the complexity of your query isn't supported by Data Services which explains your runtime exception in this case.
Judging from your query, you should be able to use the solution Nick proposed, except I think there is an error in the Where clause that he supplied. In fact, from your original sample, you don't even need the Where clause:
var ProjectionsQuery = proxy.OptionARMProjections .OrderByDescending(row => row.OptionARMRunId) .Take(1);
精彩评论