Dynamic query with WCF RIA Services - linq

I use Silverlight 4 with WCF RIA Services (domain services with EF4). Now I'd like to add a functionality, which allow an user to query data based on the criteria user selected (ad-hoc query). I've found that:
-WCF RIA Services doesn't allow anonymous types, so linq projection isn't possible.
-Exposing OData doesn't help (much), because you can't filter data at client-side.
Searching Internet, it seems I can use dynamic linq library described in the following link:
http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
In short, the above link shows how to pass search predicate to server, and execute query at the server-side.
But how about returning arbitrary data? Anonymous types can't be passed, and I don't want user to retrieve all data, but only those fields user chose. Maybe I should serialize my entity data in domain service and pass it as raw xml? Is it possible? If so, how can I do that?

For one of our scenarios we have a DomainService operation which returns xml strings, it looks something like this:
public IQueryable<WidgetInfo> GetWidgetList()
{
IList<WidgetInfo> widgets = WidgetDatabase.GetWidgets(userId);
return widgets.AsQueryable();
}
where WidgetInfo looks like this:
public class WidgetInfo
{
[Key]
public int Id;
public string Title;
public string WidgetData; // Contains XML description of data
}

I'm going to respond to returning arbitrary data. Take a look at the discussion here: https://stackoverflow.com/a/10018119/178620
I have achieved returning arbitrary data by creating a new POCO Entity, which contains IEnumerable. And I do serialization and deserialization using Json.Net Bson, which is much faster than XML.
Update: There's also the Dynamic Linq Library (https://stackoverflow.com/a/848435/178620)

Related

Filtering CassandraRepository by multiple fields dynamically

I need to filter on multiple fields of an entity dynamically when searching the CassandraRepository.
Specifically, there are multiple String fields of the entity. The user can indicate which (if any) of these fields they want to match a specified Regular expression (e.g., ".*").
However, it looks like CassandraRepository doesn't provide support for JpaSpecificationExecutor, which is what resources online typically suggest using for this purpose, giving the following issue:
Could not create query for public abstract Page JpaSpecificationExecutor.findAll(Specification, Pageable)! Reason: Page queries are not supported. Use a Slice query.
What is the appropriate way to approach this issue?
Based on the research I have done, the closest you can get is creating your own CQL Query String based on the inputs provided, and executing them on a CassandraOperations Object that you can autowire into the necessary class.

Spring Data- how to tell spring what entities to retrieve

If i have several entites, lets say :
#Entity
class Book{
String name;
Author author;
}
#Entity
class Author{
String name;
City hometown;
}
#Entity
class City{
String cityName;
}
If i want to retrieve all the books, if i use classic JPA Repository and Spring Data and just do a findAll(), it will get me all the books with all the Authors with all their home towns. I know i can use #JsonIgnore, but i think that only prevents whats being returned, not whats being looked up in the database. And also i have methods that DO want to return both books and authors, so #JsonIgnore -ing does not work for me. Is there anything like this ? To tell Spring Data what to look up and what to return ? Any links or guides or methods i don't know of, would be appreciated.
Spring Data has the concept of 'projections' which allow you to return different representations of the same Entity.
Official Documentation:
Spring Data query methods usually return one or multiple instances of
the aggregate root managed by the repository. However, it might
sometimes be desirable to create projections based on certain
attributes of those types. Spring Data allows modeling dedicated
return types, to more selectively retrieve partial views of the
managed aggregates.
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections
Where a Projection is a 'closed' projection (a projection interface whose accessor methods all match properties of the target aggregate) then the documentation notes that additionally:
Spring Data can optimize the query execution [to select only the relevant fields], because we know about
all the attributes that are needed to back the projection proxy
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections.interfaces.closed
Spring Data also allows for Projections to be specified dynamically at runtime. See further:
https://github.com/spring-projects/spring-data-commons/blob/master/src/main/asciidoc/repository-projections.adoc#dynamic-projections
First mark your relations as LAZY
Then specify what data needs to be fetched on a per-query basis.
See for example:
https://vladmihalcea.com/eager-fetching-is-a-code-smell/

How do you expose a Web API OData service that returns a combination of Entity Framework and File System results?

For example, I have a database table that contains the following fields:
ID
Type
FilePath
An Entity Framework model is created for that table. The model is used to create an EDM for an OData service.
I would like to use that Odata service to filter the database fields as well as filter the results based on the content of the files located at the file path.
For example I'd like to be able to use syntax like this to get all records where the Type starts with the word 'procedure' and the content contains the word 'test':
$filter=startswith(Type,'procedure') and substringof('test', FileContent)
I would like the database filters to be applied first so that there are less FileContents to read. I would also like to read the FileContents one by one using a stream instead of loading them all into memory.
Can this be accomplished through LINQ by creating some sort of IQueryable object?
Can this be accomplished through Web API OData by attaching a property to the EDM and treating it differently?
It may be resolved in this way:
Add a property, say Content to the entity type.
Derive ODataQueryOptions and overwrite its ApplyTo method. This is the base class:
https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Http.OData/OData/Query/ODataQueryOptions.cs
Use the derived class in the controller:
public XXXXXController
{
public IHttpActionResult(MyODataQueryOptions options)
{
var products = this.GetProducts().AsQueryable();
return Ok(options.ApplyTo(products));
}
}

Is it possible to map Linq queries from one Data Model to a query over a different data model?

I would like to provide an OData interface for my application. The examples that I have seen use EF to map the LINQ queries to SQL queries.
IMHO it this approach pretty much exposes the physical database model to the world (I know EF/NH give some flexibility, but it is limited).
What I would like the be able to do, is the following:
Define my Data Contract via some DTOs.
Have a OData Service that will let users query over my Data Contract Dtos.
Have some translation layer to translate the queries over the DTOs to queries over, let's say, EF model or NH.
Execute the translated query.
Map the results back to my Data Contracts.
Am I out of my mind or is there a solution to this problem?
I have 2 models, the "contract" model and the "persisted" model. The persisted model is what Entity Framework is mapped to. The Get method that returns an IQueryable returns a IQueryable which is just something along the lines of:
return dbContext.PersistedCustomers.Select(x => new Customer(Name = x.OtherName, ...));
At least when using DbContext as opposed to ObjectContext, Where criteria based on the contract model get translated automatically into Where criteria of the PersistedModel to be executed against the database. Hopefully the differences between the two aren't that complex that you need some weird data massaging. I'm sure there's limits to the reversal it does.
One way of doing it would be to create a ViewModel that will represent your Model and then use AutoMapper to map between them. You can use like this:
var address = _Context.Addresses.Where(p => p.AddressID == addressID).Single();
AddressVM result = Mapper.Map<AddressVM>(address);

web api odata service - return complex type

i want to create web api odata service that return reault type which consist of collection data member and additional members like this service return:
http://services.odata.org/OData/OData.svc/Suppliers?$filter=Address/City eq 'Redmond'
as you can see the result type is consist of collection data member and additional members
can anyone send me a sample how to do it?
i can't succeed to create this kind of complex type and to be able filter the collection items by there values
as yuo can see in this query it return all the result without filter the items
services.odata.org/OData/OData.svc/Suppliers
i want to be able filter this type like this:
services.odata.org/OData/OData.svc/Suppliers?$filter=Address/City eq 'Redmond'
in this query i managed to filter the collection member items and still returning the other data members.
If you just want to implement filters like: services.odata.org/OData/OData.svc/Suppliers?$filter=Address/City eq 'Redmond'
Please check the sample at http://aspnet.codeplex.com/SourceControl/changeset/view/903afc4e11df#Samples%2fNet4%2fCS%2fWebApi%2fODataServiceSample%2fReadMe.txt
It has a supplier and address model with queryable attribute. It should work with the same $filter query.
Odata support was implicit in asp.net webapi RC.
You just had to return a IQueryable from you Actions and mark it with [QueryableAttribute].
Only this much supported querystring based data filtering.
I was a bit disappointed when I saw the [QueryableAttribute] doesnt build in RTM.
In RTM it’s available as a separate package, Microsoft.AspNet.WebApi.OData on Nuget in a preview/alpha form. Full release is coming later this fall. You can grab it from here(http://www.nuget.org/packages/Microsoft.AspNet.WebApi.OData). There is a nice overview post available (http://blogs.msdn.com/b/alexj/archive/2012/08/15/odata-support-in-asp-net-web-api.aspx)

Resources