There are two classes with identical field structure: WebMessage
and WebMessageDto
.
I have a DataGrid which can work with both classes. And I have a RIA Service which can provide only WebMessageDto
because WebMessage
has navigation properties and they cannot be serialized.
Now, DataGrid should query RIA Service method returning IQueryable<WebMessageDto>
. I need handle DataGrid's query and execute it on ORM's Table<WebMessage>
, then transform result to WebMessageDto
type and return it to DataGrid.
I started to implement custom IQueryable interface and I can handle expression.
public class WebMessageQueryContext
{
// Executes the expression tree that is passed to it.
internal static object Execute(Expression expression, bool isEnumerable)
{
// DataContext.WebMessages is a ORM table which returns IQueryable<WebMessage>
List<WebMessage> list = DataContext.WebMessages.Provider.Execute(expression);
return WebMessageDto.ConvertFrom(list); // returning List<WebMessageDto>
}
}
The code above will make recursive calls to this method. And I found microsoft's sample where queryable source changes in ExpressionVisitor and now I change original source to ORM's table.
protected override Expression VisitConstant(ConstantExpression c)
{
if (c.Type == typeof(WebMessageDtoQuerySource<WebMessageDto>))
return Expression.Constant(DataContext.WebMessages);
return c;
}
I'm getting exception when I execute the expression:
Expression of type 'System.Data.Linq.Table'1[WebMessage]' cannot be used for parameter of type 'System.Linq.IQueryable'1[WebMessageDto]' of method 'Int32 Count[WebMessageDto](System.Linq.IQueryable
1[WebMessageDto])'`
There's no much information about IQueryableProviders and I don't know what to do... Who can answer, can I do it theoretically?
Sorry guys, I was wrong. Before question edit I wrote that Select
applied to IQueryable
before Where
causes loading all table rows in memory and then executing Where
statement. But actually such behavior was caused by incorrect implementation of custom linq provider.
When I used datagrid without custom linq provider I mentioned that Select
executes after Where
even when Select
is applied before Where
.
In my code:
public IQueryable<WebMessageDto> Dtos
{
get { return db.WebMessages.Select(r => new WebMessageDto { Id = r.Id });}
}
My DataGrid queries this method with Where/OrderBy/GroupBy
statements and conversion to WebMessageDto
occurs after them.
So, Alex Key's answer is also applicable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With