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

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));
}
}

Related

Handling filtering by a particular field in JPA Spring Boot

I want to implement a filtering feature based on the properties of an entity that I have stored in my db.
I'm using a JPA query to do so. The problem that I'm facing is concerned with entity manager which requires the class of the object that is required to return.
public List<CountryEntity> getSortedCountries(String field, String type) {
return entityManager.createQuery(GET_ALL_SORTED.concat(field).concat(" " + type), CountryEntity.class).getResultList();
}
When I select only one field, let's say the name of the country, the query returns a String and not an object of type CountryEntity.
What is the best approach to handle this problem? Should I create classes for every single case or is there another way that I'm missing?

Assigning values to unmapped property

Suppose, I have a Customer class with some properties like
name,
id,
object of CompetentAuthority class etc.
name,id etc is mapped in .hbm file but i have taken icollection of CompetentAuthority object and I didnt do any entery in .hbm file for CompetentAuthority(one-to-many).
In CompetentAuthority class i have taken Customer object and in .hbm file of CompetentAuthority i did many-to-one relationship.
Nnow,i want list of customers with it's CompetentAuthority list but as its just an object and no mapping is done,criteria API doesn't allow me to do innerjoin;it gives me error like "cannot resolve property"
Is there any way to achieve this.
If you are wanting to use the Criteria API to apply an INNER JOIN, then no you cannot do that. The CompetentAuthority object needs to be mapped with NHibernate and the Customer object's mapping file will need to be modified to establish the relationship between the two entities.
If for some reason you are not able to map the CompetentAuthority, you could take advantage of mixing the ISession.CreateSQLQuery() method and the Transformers.AliasToBean() method which will allow you to hydrate an unmapped entity.
For more information on this technique, please refer to the Official NHibernate documentation section titled "Returning non-managed entities" or search around for using the AliasToBean() method: http://nhibernate.info/doc/nh/en/index.html#d0e11066

Using LINQ to compare a searchstring with the value of all the string properities of a EF class

In my ASP.NET application I have an EF Product class (derived from Product DB table) and I want to perform search functionality on its string fields by using inline LINQ.
Since I predict the name and amount of the fields (properties) will change I do not want to strongly couple my code with the table definition. How can I compare the values of all the fields in the table with a search string by iterating through all table fields (properties)?
I know one option is through reflection, is there any easier and more immediate way to fulfill this task?
In the end, your EF class is still just a normal .NET class. Unless EF explicitly provides some library for looping through properties (it doesn't that I know of), you'll still need to use reflection to do this.
var properties = typeof(Product).GetProperties(BindingFlags.Instance);
foreach (var property in properties)
{
...
}

Partial loading of Entity Framework entities and passing them to presentation layer

If I want to select only few columns when retrieving data for an EF entity and cast them to the Entity type, I am not able to do that because it throws an error as mentioned in this post
The entity cannot be constructed in a LINQ to Entities query. I don't want to select all the columns, because I need only few of them. I can use anonymous types, but if I am using repository pattern and want to encapsulate all data access code in repository object and pass strongly typed object collection to the controller (not an anonymous object collection), how can I achieve that? Is the only option to define a DTO object for every subset of the properties for the EF entity? I know there is a risk of losing data with partial loaded entities, but if I am ready to take the risk and want full control over data updates, is that not possible?
for example I would like the "ProductRepository" method signature to be like this
public IEnumerable<Product> GetProducts(int categoryID) //selection of subset of data
and I want to pass this product collection from the controller to the view (in ASP.NET MVC project) and in the view I want to have strongly typed model (with intellisense) object. Is this possible? if not, I may have to reconsider using EF for my project due to this limitation. I am using EF 4.1 version.
Yes the option in this case is special object for each subset of properties you want to select. You can call the object DTO because it is just a result of the projection. This is the correct approach because if your UI doesn't need other properties of entity type it is correct to pass it only specialized ViewModel.
Another more complex (and worse) option is selecting anonymous type inside your Linq-to-entities query, calling ToList and after that construction the real entity type. Partial entity selection is not allowed and projecting to mapped entity types is not allowed as well. That is the reason why you have to use such a cumbersome approach. Example:
// Select anonymous projection
var query = from x in context.Entities
where ...
select new { ... };
// Repopulate entity type
var reultSet = query.ToList().Select(x => new Entity { ... });
Yes, what you want is totally possible using viewmodels instead of entities. Here is example controller code:
var productEntities = productRepos.GetProducts(6);
var productViewModels = Automapper.Mapper
.Map<IEnumerable<ProductViewModel>>(productEntities);
return View(productViewModels);
Your view model will have only the properties it needs for the view. Check out automapper.

Dynamic query with WCF RIA Services

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)

Resources