Collection Exists Criteria in WCF Data Services - linq

I'm trying to ask my OData service:
"Give me all the Products that do not have a Category"
with the Products and Category have a m2m relationship.
I've tried:
from p in Products
where p.Categories == null
select p
and
from p in Products
where !p.Categories.Any()
select p
and
from p in Products
where p.Categories.Count == 0
select p
but all of these give me not supported exceptions.
I'm not looking for alternatives or options. Please don't answer with other options.

My experience with WCF Data Services is that the client subset of LINQ to rest is lacking.
My biased option would be to just move it to server side where you have access to the full implementation of LINQ to entites? (or whatever you are using to implement your Data Service).
[WebGet]
public IQueryable<Products> GetProductsWithoutCategories(){
/*start psudo code
from p in Products
where p.Categories.Count == 0
select p
*/
}

This is not supported:
http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataservices/thread/b505d630-c808-4bde-b08e-3ce1dd17f621/
The OData URL query language currently
doesn't support this type of query. As
a result the client's LINQ processor
doesn't support it either. If you
think it's valuable to add such
functionality please use our connect
site to suggest the feature, it makes
our planning job easier next time
around.
https://connect.microsoft.com/dataplatform/content/content.aspx?ContentID=15540&wa=wsignin1.0
As a workaround you could probably use
service operation. Define a service
operation which returns IQueryable (so
that you can compose some more query
operators on the result from the
client) and use the server side
provider to issues the query above.

My solution to this problem was to $expand the related field in the query, and then test if that field was empty or not...
JArray _array = (JArray)main_table_object["some_related_field"];
if (_array.Count > 0)
continue;
.. this is in the context of queries from Windows 7 phone to a WCF service using JSON as the message format.

Related

MS CRM Online: Get all accounts with more than X contacts

Is it possible to get all accounts in MS CRM Online with more than X contacts via odata (this is probably not possible via FetchXML)?
Something like (dummy code, does not work):
accounts?$apply=aggregate(contact_customer_accounts with countdistinct as total)/filter(total gt X)
Unfortunately, this is not possible as it is not straight forward with a single query using fetchxml (no support for subquery and aggregation with having clause) or web api. You can pull all the results and do aggregation using LINQ or other ways.
Compared to that, using a single rollup attribute to count the child contact records on parent account (not a calculated field) is the easiest option.

How does entity framework optimize linq queries

I am using Azure Mobile Web Services with an Entity Framework Database and am wondering about how to structure my linq query. I have a UserSetting and a User table, with UserSetting being a one-to-many with User. However, since I don't have referential constraints, I don't have a UserId property to query against in linq. So, I'd like to, in one operation, get the UserId and get all UserSettings belonging to the user. Also, I'm posting here because I'm having a hard time figuring out break points on a Web Service when a query is run so I can look at the SQL
So, my question is are these two queries the same thing?
return Query().Where(setting => setting.User.AccountId == currentUser.Id);
return from setting in Query()
let user = context.Users.SingleOrDefault(user => user.AccountId == currentUser.Id)
where setting.User == user
select setting;

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)

LINQ to CRM - OR in Where clause

I am trying to bring some data from Dynamics CRM 2011 using LINQ. The goal is to bring all Contact records that have changes since certain date OR have a child entity (PERC files) changed since that same date. The query looks like that:
// Bring all students who have changes (at Contact entity) after specific date
// momentInTime or the status of any of their perc files has been changed since
// that date
var students = (from c in ContactSet
join pl in cga_portallogonSet on c.Id equals pl.cga_ContactId.Id
join ef in cga_percfileSet on c.Id equals ef.cga_StudentId.Id
where
(pl.cga_PortalLogonRole.Value == 284970000) // student
where
(c.ModifiedOn >= momentInTime || c.CreatedOn > momentInTime)
||
(ef.cga_statuschangedate >= momentInTime)
select c.cga_StudentNumber).Distinct().ToList();
This produces the following error message:
'Contact' entity doesn't contain attribute with Name = 'cga_statuschangedate'.
I cannot figure out how to do OR on two different entities. The MSDN says you need WHERE clause for each entity:
where Clause
In order to filter the result set, where clauses can be added against one or more of the >entities. Each where clause may only contain conditions against an individual entity type. >A composite condition involving multiple entities is not valid. Instead, each entity >should be filtered in separate where clauses.
http://msdn.microsoft.com/en-us/library/ff681565.aspx
Is there another way of achieving what I need?
Unfortunately you cannot achieve what you want in a single linq statement beacuse the liunq provider they use boils down to fetchXML, and fetchXML does not support the scenario you are using.
More detail... Fetch gives you condition's inside of entity's or link-entity's. These condition elements cannot have attributes in them from other linked entities, only the direct parent entity or link-entity. Here is one of many microsoft forum posts referencing this limitation of fetchXML
Probably not the answer you were looking for, eh? As an ugly alternative you you can run two separate queries and filter in memory (as damaging as that may be to performance). Or better yet if you are an on-premise deployment you can write some sql against the filtered views. Good luck.

How to implement a Query with IQueryable in SilverLight

I have two tables customers, pay and want to implement a gridview in silverlight with the outcome of the relationship of these two tables, the query is as follows
SELECT Pa.Tipo_Pagare, Pa.Pagare, Pa.Rut, Cli.Nombre
FROM Cred_Crexsa.dbo.Pagare AS Pa INNER JOIN
Cred_Crexsa.dbo.Clientes AS Cli ON Pa.Rut = Cli.Rut
WHERE (Pa.Nulo <> 0) AND (Pa.Extraviado <> 0)
Thank you very much
Leonardo Moreno Flores
Silverlight doesn't have any DB libraries. You'll need to write a webservice. Either reconstruct the query on the web server using your ORM of choice (many of them now support LINQ features, if you prefer) or have it call a stored procedure based on the SQL you posted.

Resources