"the method join is not supported" with Tridion OData service & Linq - linq

I'm trying to a join CustomMeta & PageContents to select a specific page via some metadata that has been set, but I'm getting a "the method join is not supported" error. I think the issue is with my linq statement, as the error happens before anything gets sent to the OData service. But what is the issue exactly? The linq statement looks fine to me:
var pages2 = (from p in cds.PageContents
join m in cds.CustomMetas on p.PageId equals m.ItemId
where m.ItemType==64 && m.KeyName=="SomeKey" && m.StringValue=="SomeValue"
select p).ToList<SDLODataClient.SDLOData.PageContent>();
UPDATE 1
This Tridion OData article has an example of a join but some of the MS Linq to OData articles I'm reading seem to suggest that joins aren't supported in Linq to OData (here)

To my knowledge, LINQ queries against Data Services (OData) does not support several methods. The one you are using is join is also falls under the same category hence you are seeing the error even though the syntax is very valid from LINQ point of view. join falls under "Projection and filtering operators" which is not supported query with LINQ against OData .
Here is the link that explains all the unsupported methods (Refer section - Unsupported LINQ Methods)
http://msdn.microsoft.com/en-us/library/ee622463(v=vs.100).aspx
Back to your question, I am not quite how to achieve what you are looking for but I would try the following (you might have to get the results in multiple iterations):
Get the list of Page IDs that match the custom meta query (sample snippet - not tested)
_client.CustomMetas.Where (
m => m.KeyName == "somekey" && m.StringValue == "somevalue" && m.ItemType == 64)
.ToList();
Now you could query Page Contents using the above page ids. You might have build the filter type query for each page id.
Hope this helps.

Have you tried using the concept of expand ?
In OData service we do not have the join query but there is Expand keyword, wherein two entities (tables) that have a foreign key relationship can be used together to get a result set. It works as follows:
from item in table1.Expand(table2).AsEnumerable()
where (item.property1.Equals("x") & item.table2[0].prop2.Equals("y"))
select item
Here the second entity is exposed as an property of the first entity.

Related

Spring JPA paginated query with Join Fetch - Count Query gives fetch error

(Note: all code examples are extremely simple. I know there are other ways to do such simple queries. The problem I am demonstrating, however, is a bigger deal for more complex queries).
There is a known issue with Spring JPA Repositories and paginated queries that I'm really hoping there is a good solution for. In JPQL, it is possible to use JOIN FETCH to specify that I want to eagerly fetch a related entity, rather than doing it lazily. This avoids the N+1 problem, among other things. JOIN FETCH requires that the owner of the association is included in the select clause. Here is a very simple example of the type of query I'm talking about:
#Query("""
SELECT p
FROM Person p
JOIN FETCH p.address
""")
Page<Person> getPeopleAndAddresses(Pageable page);
The problem with this kind of query is the pagination piece. When returning a Page, Spring will do the query I wrote but then also do a count query to get the total possible records. Spring appears to take my query exactly as written, and just replace SELECT p with SELECT COUNT(p). Doing this means that the owner of the JOIN FETCH association is no longer present in the SELECT clause, which then results in the JPQL giving an error.
The only way I know how to resolve this is to construct the query with separate query and countQuery values, like this:
#Query(query = """
SELECT p
FROM Person p
JOIN FETCH p.address
""", countQuery = """
SELECT COUNT(p)
FROM Person p
""")
Page<Person> getPeopleAndAddresses(Pageable page);
This resolves the JPQL JOIN FETCH error, because the count query no longer contains a JOIN FETCH clause. However, for complex queries with sophisticated JOINs and WHERE clauses, this will lead to excessive code duplication as I will have to write all that logic in two places.
This seems like the kind of issue where there really should be a better solution available. I'm exploring various alternatives, including Specifications (mixed feelings), Blaze Persistence, and others. However, I'm wondering if there is some way in Spring itself to resolve this issue so that the first code example would work without an error?

Power Automate D365 Virtual column OData Filter Error

I've been looking for some articles regarding this but havn't seen anyone have this issue. We are trying to reference a Virtual Field named "_ownerid_type". Expression: _ownerid_type eq 'systemusers' However it returns an error. I can see that the field is available in the Triggerbody and have performed similar filters with guids. Does anyone have any direction for me? Thanks in Advance.virtual field in Trigger output
OData Filter Expression
{ "error": {
"code": "0x80040203",
"message": "Exception parsing _ownerid_type eq 'systemusers' submitted for attribute filterexpression of callback registration.
Target entity: incident. Exception: Microsoft.OData.ODataException:
Could not find a property named '_ownerid_type' on type
'CallbackRegistration.incident'.\r\n at
Microsoft.OData.UriParser.EndPathBinder.GeneratePropertyAccessQueryForOpenType(EndPathToken
endPathToken, SingleValueNode parentNode)\r\n at
Microsoft.OData.UriParser.EndPathBinder.BindEndPath(EndPathToken
endPathToken)\r\n at
Microsoft.OData.UriParser.MetadataBinder.Bind(QueryToken token)\r\n
at
Microsoft.OData.UriParser.BinaryOperatorBinder.GetOperandFromToken(BinaryOperatorKind
operatorKind, QueryToken queryToken)\r\n at
Microsoft.OData.UriParser.BinaryOperatorBinder.BindBinaryOperator(BinaryOperatorToken
binaryOperatorToken)\r\n at
Microsoft.OData.UriParser.MetadataBinder.Bind(QueryToken token)\r\n
at Microsoft.OData.UriParser.FilterBinder.BindFilter(QueryToken
filter)\r\n at
Microsoft.OData.UriParser.ODataQueryOptionParser.ParseFilter()\r\n
at System.Web.OData.Query.FilterQueryOption.get_FilterClause()\r\n
at
Microsoft.Crm.ObjectModel.EdmModelEvaluator.EvaluateFilterExpression(String
filterExpression, ODataQueryOptions queryOptions)\r\n at
Microsoft.Crm.ObjectModel.EdmModelEvaluator.EvaluateFilterExpression(String
filterExpression)\r\n at
Microsoft.Crm.ObjectModel.CallbackRegistrationService.<>c.<.cctor>b__50_0(EdmModelEvaluator
evaluator, String testValue)\r\n at
Microsoft.Crm.ObjectModel.CallbackRegistrationService.ValidateInputEntity(IBusinessEntity
entity, ExecutionContext context, IFeatureDetailContainer
featureDetailContainer)" } }
Power Automate / Flow is returning that type property when a lookup is involved (for lookup here I mean standard and polymorphic lookup, owner and customer).
That property is not returned when executing a query against the Web API directly (I don't know if they are using some special annotations in order to retrieve it) but the #Microsoft.Dynamics.CRM.lookuplogicalname property contains the table name and in my opinion that should be checked, not the type one.
But you can't filter on these two properties (lookuplogicalname or type). Theoretically you can do a filter on the relationship column checking the id of the table, for example something like:
owninguser/systemuserid ne null
BUT Web API (more related to the OData implementation if I am correct) consider this kind of filter as Left Outer (not Inner Join) meaning it will return also rows where the records are actually owned by teams, making this kind of filter criteria useless (because you just want Cases owned by users if I understood correctly what you are doing).
As Alternative is to use a FetchXML query, but I am not aware of a way to execute a FetchXML query with the action you are using (the When a row is assigned to a user)
I know what I wrote is not a complete answer to your problem but it can give you some context on what is happening

LINQ value.Contains function error

i am facing an error while using contains function of LINQ query
following error occured
Contains is not supported, doing a substring match over a text field is a very
slow operation, and is not allowed using the Linq API.
The recommended method is to use full text search (mark the field as Analyzed and
use the Search() method to query it.
here is my query
query = from u in Session.Query<Article>() where u.Tags.Contains(tags) orderby u.CreationDate descending select
StartWith/EndsWith works fine but it is not full filling my requirements
As the error states, Contains won't work and you need to use Analyzed fields. You can start here: http://ravendb.net/docs/client-api/querying/static-indexes/configuring-index-options

Linq OData "Where" clause on nested list

Say I have the following query OData Linq Query (run against http://odata.netflix.com/v2/Catalog):
Genres.Where(x=>x.Name=="Adventures")
.Select(y=> new
{
Genre = y.Name,
Movie = y.Titles.Select(l=> new
{
l.Name,
l.AverageRating
})
})
How could I change this query to give me the rows where AverageRating was 3?
(NOTE: The point of this question is to find out how to do a where clause on properties of an expanded sub list of my main level query item. My real query is not even against the Netflix OData feed.)
The short answer is that it's not possible currently.
The $filter always (and only) applies to the top-level entity set. There's currently no way to filter expanded entity sets.
The $filter can reach inside the expanded entity sets but the result will always filter the top-level set. In V2 it works for singleton navigation properties (the expression in $filter can traverse those), in V3 you can use the any/all to also incorporate collection navigation properties.
The reason this can't work is that the OData protocol doesn't define the URI syntax for nested filters. In fact it doesn't define almost any operator on the expanded entity sets except for the expansion itself and projections.

Dynamic Query using Linq To SQL According Multiple Fields

Hi Experts
I have a special question About dynamic Linq to Sql.
Consider we want to search in a table according two fields*(LetterNo(string) and LetterDate(Datetime))*
.OK the problem is user can enter on of that fields or even both.
I searched in the internet and found "Linq.Dynamic" library in ScottGu weblog.but in that library if we want to use SqlParameter in exported command we should use #0 and param for that.problem is I don't know how many fields user entered.
I want use one query for that and no external tool like "Linq Kit PredicateBuilder".
If I create my query string Manually(and execute using ExecuteCommand) then I will abdicate SqlParameter and risk of Sql Injenction growing up.
How Can do that?
thanks
I suspect you are wanting to do something like the following:
IQueryable<Letter> query = context.Letters;
if (!string.IsNullOrEmpty(LetterNo))
query = query.Where(letter => letter.LetterNo == LetterNo);
If (LetterDate.HasValue)
query = query.Where(letter => letter.LetterDate == LetterDate);
When you execute query, it will combine the necessary expressions and issue a single query to the database based on the user's input.

Resources