This thread looks to be a little on the old side and therefore may no longer be relevant. Please see if there is a newer thread on the subject and ensure you're using the most recent build of any software if your question regards a particular product.
This thread has been locked and is no longer accepting new posts, if you have a question regarding this topic please email us at support@mindscape.co.nz
|
I built some code that used Linq to SQL to retrieve data, and Linq to XML to create an XML document from the results. It worked pretty well, but to build one XML element I had to call a local method. This worked with Linq to SQL as well, but it appears that the LightSpeed implementation doesn't like method calls within select statements. A simplified example would be this:
public void BuildProductDocument()
{
var xml = new XElement( "productDocument",
from p in unitOfWork.Products
select new XElement( "product",
new XElement( "name", p.Name ),
new XElement( "description", BuildDescription( p ) ) ) );
}
protected string BuildDescription(Product p)
{
.. do something long here..
}
|
|
|
Oops, here is the exception
System.NotSupportedException was caught
Message="The method 'BuildDescription' is not supported."
Source="Mindscape.LightSpeed.Linq"
StackTrace:
at Mindscape.LightSpeed.Linq.TranslatableExpressions.TranslateMethod(MethodInfo method)
at Mindscape.LightSpeed.Linq.LinqQueryTranslator.VisitMethodCall(MethodCallExpression m)
at Mindscape.LightSpeed.Linq.ExpressionVisitor.Visit(Expression exp)
at Mindscape.LightSpeed.Linq.ExpressionVisitor.VisitExpressionList(ReadOnlyCollection`1 original)
at Mindscape.LightSpeed.Linq.ExpressionVisitor.VisitNew(NewExpression nex)
at Mindscape.LightSpeed.Linq.LinqQueryTranslator.VisitNew(NewExpression nex)
at Mindscape.LightSpeed.Linq.ExpressionVisitor.Visit(Expression exp)
at Mindscape.LightSpeed.Linq.ExpressionVisitor.VisitExpressionList(ReadOnlyCollection`1 original)
at Mindscape.LightSpeed.Linq.ExpressionVisitor.VisitNew(NewExpression nex)
at Mindscape.LightSpeed.Linq.LinqQueryTranslator.VisitNew(NewExpression nex)
at Mindscape.LightSpeed.Linq.ExpressionVisitor.Visit(Expression exp)
at Mindscape.LightSpeed.Linq.ExpressionVisitor.VisitExpressionList(ReadOnlyCollection`1 original)
at Mindscape.LightSpeed.Linq.ExpressionVisitor.VisitNewArray(NewArrayExpression na)
at Mindscape.LightSpeed.Linq.ExpressionVisitor.Visit(Expression exp)
at Mindscape.LightSpeed.Linq.ExpressionVisitor.VisitExpressionList(ReadOnlyCollection`1 original)
at Mindscape.LightSpeed.Linq.ExpressionVisitor.VisitNew(NewExpression nex)
at Mindscape.LightSpeed.Linq.LinqQueryTranslator.VisitNew(NewExpression nex)
at Mindscape.LightSpeed.Linq.ExpressionVisitor.Visit(Expression exp)
at Mindscape.LightSpeed.Linq.Sqo.Select.OnVisit(LinqQueryTranslator visitor, MethodCallExpression expression)
at Mindscape.LightSpeed.Linq.QueryMethodBase`1.PerformVisit(LinqQueryTranslator visitor, T expression)
at Mindscape.LightSpeed.Linq.ExpressionVisitor.Visit(Expression exp)
at Mindscape.LightSpeed.Linq.LinqQueryTranslator.Translate(Expression expression, IUnitOfWork unitOfWork, String viewName)
at Mindscape.LightSpeed.Linq.LinqQuery`1.System.Collections.IEnumerable.GetEnumerator()
at System.Xml.Linq.XContainer.AddContentSkipNotify(Object content)
at JDC.Gbase.Central.Business.MappingService.UpdateDealerLocationKml() in D:\Projects\WebSites\Gbase\trunk\src\JDC.Gbase.Central\JDC.Gbase.Central.Business\MappingService.cs:line 68
at JDC.Gbase.Central.Business.MappingService.UpdateDealerMap() in D:\Projects\WebSites\Gbase\trunk\src\JDC.Gbase.Central\JDC.Gbase.Central.Business\MappingService.cs:line 38
at JDC.Gbase.Central.Web.Controllers.HomeController.UpdateMap() in D:\Projects\WebSites\Gbase\trunk\src\JDC.Gbase.Central\JDC.Gbase.Central.Web\Controllers\HomeController.cs:line 26
InnerException:
|
|
|
I think this occurs because we always try to translate operations on LINQ range variables (such as the p.Name projection) into SQL. At the moment there's no way to provide for the translation of your own methods into SQL, or to identify a method as client-side, so unknown methods will result in NotSupportedException. We will have a think about how to address this but it probably won't be fixed soon. In the meantime, you should be able to work around it by forcing everything client-side: from p in unitOfWork.Products.ToEnumerable() The only change here is to add in a call to ToEnumerable() (you could also use ToList etc.) to get the C# compiler to run this as a LINQ to Objects query over the LightSpeed result set, rather than a "native" LINQ to LightSpeed query which gets translated to SQL. Note that if your real scenario has e.g. where or order by clauses you can still use them and have them translated, but you need to be careful with the placement: from p in (from p1 in unitOfWork.Products i.e. the ToEnumerable must be applied to the part of the query that you want to run on the server, then the projection query must range over the result of the ToEnumerable. Hope this makes sense -- let me know if not! |
|
|
Thanks, that definitely solved it. Now I know why Oren and Connery are always complaining about how hard building Linq providers is.. its nuts..
|
|
|
You need to use AsEnumerable, not ToEnumerable. I have the same type of issues when I pass the Context around to items that take IEumerable<T>. Unless I use AsEnumerable I get cast exceptions. Joe Feser |
|
|
[quote user="joe.feser"]You need to use AsEnumerable, not ToEnumerable.[/quote] Doh! Thanks, Joe. |
|