This project has moved and is read-only. For the latest updates, please go here.
1

Closed

Query Projections

description

Is it possible to project a query into a poco?
(ie)
IQueryable<POCO> data = this.CifDbContext.Ics.Where(x => x.active == true) .Select(x => new POCO { customer = x.customer, address = x.address}

Declaring type 'CifManiModel.Projections.POCO' could not be reconstructed",

If try to create a BS iQueryable as a POP
private static readonly Func<Type, IQueryable> _queryableResourceProvider = type =>
{
if (type == typeof(Ic)) return context.Ics.AsQueryable();
if (type == typeof(CifManiModel.Projections.POCO)) return bsContext.POCO.AsQueryable();
}
I get
The specified LINQ expression contains references to queries that are associated with different contexts.

Any Sugestions?

Thanks,
Mike
Closed Aug 13, 2016 at 1:07 AM by ChristofSenn

comments

mpisano wrote Mar 30, 2016 at 11:52 PM

ok I'm over the POCO issue

I had to
    class tResolver : Aqua.TypeSystem.ITypeResolver
    {
            if (typeInfo.FullName == "CifManiModel.Projections.POCO") return typeof(CifManiModel.Projections.POCO);
            return typeInfo.Type;
        }
and then

expression.Execute(_queryableResourceProvider, typeResolver: new tResolver())'

mpisano wrote Mar 31, 2016 at 12:07 AM

I am having a problem an additional issue now....

Some of this code is also accessed by a Breeze Controller that is trying to add Odata Verbs to the RemoteQueryable - this worked perfectly prior and now is throwing a

System.Web.Http.HttpError, System.Web.Http","Message":"An error has occurred.","ExceptionMessage":"The type arguments for method 'System.Linq.Enumerable.ToList<TSource>(System.Collections.Generic.IEnumerable<TSource>)' cannot be inferred from the usage. Try specifying the type arguments explicitly."

Do you have any experience with ODataQueryOptions ?

mpisano wrote Mar 31, 2016 at 10:56 PM

so Breeze calls

queryable = queryOptions.ApplyTo(queryable, querySettings);

which calls into system.web.Http.Odata for my $top command
    public static IQueryable Take(IQueryable query, int count, Type type, bool parameterize)
    {
        Expression takeQuery = Take(query.Expression, count, type, parameterize);
        return query.Provider.CreateQuery(takeQuery);
    }
this calls back to AsyncRemoteQueryProvider CreateQuery
    public IQueryable CreateQuery(Expression expression)
    {
        var elementType = TypeHelper.GetElementType(expression.Type);

         return new RemoteQueryable<dynamic>(this, expression);
        // return new RemoteQueryable(elementType, this, expression);
    }
Changing the return type to <Dynamic> seems to have fixed the problem, but I'm still testing

mpisano wrote Mar 31, 2016 at 11:06 PM

Seems ok, I've also now added additional constructor, to pass the true element type to _elemntType
internal sealed partial class RemoteQueryable<T> : RemoteQueryable, IRemoteQueryable<T>, IOrderedRemoteQueryable<T>
{
...
    internal RemoteQueryable(Type elemntType, IRemoteQueryProvider provider, Expression expression)
        : base(elemntType, provider, expression)
    {
    }
...
}

and now
    public IQueryable CreateQuery(Expression expression)
    {
        var elementType = TypeHelper.GetElementType(expression.Type);
        return new RemoteQueryable<dynamic>(elementType, this, expression);
    }

HTH - Still Testing...
Mike

mpisano wrote Apr 10, 2016 at 2:14 PM

Everything is working great so far, I did run in to an issue with the query expression wrapping null checks around all the odata predicates (top\skip\take) which was unneccessary and different then the queries created against true DB providers.

For anybpdy else using Remote Linq with Odata or Breeze Controllers make sure you add HandleNullPropagation attributes

[Queryable(HandleNullPropagation = HandleNullPropagationOption.False)]
or
[BreezeController(HandleNullPropagation = System.Web.Http.OData.Query.HandleNullPropagationOption.False)]


HTH
Mike Pisano