I am using FetchXml to query CRM 4.0. We have a special case that will require a composite join between CRM entites. The FetchXml schema indicates that multiple link-entity elements are allowed, and it also indicates that multiple filter/condition elements can be added to a link-entity. The problem I'm facing is that the value attribute of the condition element does not appear to permit an entity/column name. It expects an explicitly declared value.
For example, FetchXml lets you specify this:
<link-entity name='myentity' from='column1' to='column2'/>
... which does the T-SQL equivalent of this:
JOIN myentity on column1 = column2
And it lets you specify this:
<link-entity name='myentity' from='column1' to='column2'>
<filter type='and'>
<condition attribute='column3' operator='eq' value='myvalue' />
</filter>
</link>
... which is the T-SQL equivalent of this:
JOIN myentity on column1 = column2 AND column3 = 'myvalue'
FetchXml does not appear, however, to provide an equivalent of this:
JOIN myentity on column1 = column2 AND column3 = column4
Note the difference. FetchXml provides for conditions in the join, but it does appear to provide for a composite join, that is, a join across multiple columns.
Has anyone out there in cyberspace been able to perform a composite join using FetchXml in CRM 4.0? Thanks!
More information:
I'm hunting an answer that uses FetchXml to accomplish this - not SQL or the QueryExpression syntax. The SQL above is there just to explain the concept.
No, it doesn't permit this. Fetch XML is pretty limited when it comes to anything non-basic in joins. If I'm curious I usually test my query using Stunnware Tools. If it is not exposed there it probably can't be done.
Unfortunately, in situations like these these I usually end up (am forced into) taking a multiple query approach to the problem.
I know you said you're not interested in this - but I'm pretty sure QueryExpression won't handle it either. In my experience it only offers a subset of the fetchxml functionality.
Related
(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?
I am looking for the equivalent of this feature of T-SQL:
SELECT *
FROM dbo.users
WHERE CONTAINS (name, 'Jack')
in Entity Framework.
Thanks.
P.S. "contains" in linq is equivalent of LIKE in TSQL (eg., '%jack%'). I'm not looking for this because this kind of search, especially on large databases may affect the performance.
The CONTAINS keyword is part of the full-text search capability in SQL Server - and as of this day, EF doesn't natively support full-text searching.
There are some approaches out there using EF "interceptors" or plain and simple T-SQL stored procedure to include this functionality into EF - but it's not part of the EF package provided by Microsoft.
See these other SO questions:
Entity Framework, Code First and Full Text Search
How to execute a full text search using entity framework 6)
I think it's just users.Where(x => x.name.Contains("jack"));
In fact, In SQL, it should be
SELECT *
FROM dbo.users
WHERE name like '%Jack%'
And in EF, It equals to
var result = dbContext.users.Where(p => p.name.Contains("Jack"))
Not able to get optionset string from Dynamics CRM to SQL Server using Azure data factory.
I am using Azure data factory to move data from Dynamics CRM to SQL DB. I used fetchXML query to get the data from source (CRM). I am able to get normal string and guid type values without any issue.
But the optionset field from CRM is coming as Int32 type (ie, I am getting the value of optionset, not the string).
How can I fix this issue?
I'm going to have to sync the stringmaps entity too as I exceeded the link-entity limit for a given FetchXML query.
The following will bring in the textual value of an OptionSet selection.
<link-entity name="stringmap" from="attributevalue" to="____" visible="false" link-type="outer" alias="____">
<filter type="and">
<condition attribute="objecttypecode" operator="eq" value="___"/>
</filter>
<attribute name="value"/>
</link-entity>
to should be the name of the OptionSet column on the host/root entity
alias whatever you want to call the column in the output. I used the same value as to
value This is the object type code for your host/root entity. It is an integer value.
Probably you are using this approach to get the fetchxml resultset as Dynamics source to dumping into SQL using Azure Data factory. The problem you are facing is unable to consume the formatted text value for that picklist option.
We will do consume the formatted value using below syntax in code: Reference
//Option set
var industrycodeValue = accountDetails['industrycode'];
var industrycodeTextValue = accountDetails['industrycode#OData.Community.Display.V1.FormattedValue'];
If you cannot do such thing, then it’s better to dump another table in your SQL called stringmap which will store all the picklist options across the system.
Then you can inner join both tables to get the necessary data.
select INC.TicketNumber[Case ID],SMT.Value[Status Name], SMT.AttributeValue[Status Value]
from incident as INC inner join StringMap as SMT
on INC.StatusCode = SMT.AttributeValue
where SMT.AttributeName='statuscode' and SMT.ObjectTypeCode=112
Read more
I understand <link-entity> is used to do joins, but can you help me translate the following into english?
<entity name = "example">
*insert a bunch of attributes*
<link-entity name="providercertification" from="providerid" to="vendorid" alias="aa">
I understand <link-entity> is used for joins, but the join type is not specified, so that is throwing me off. How does the link-entity work if no join type is specified? Is it automatically an inner join?
Also, which column does the from part apply to? The very first entity or the one specified in the <link-entity>?
Same question for the from part.
Per documentation the below query is totally valid, which means alias, from & link-type are optional.
from always refer to same entity as link-entity node (primary key systemuserid of systemuser in this case). to refers to attribute of entity parent node (owninguser of account in this case)
<entity name='account'>
<attribute name='accountid'/>
<attribute name='name'/>
<link-entity name='systemuser' to='owninguser'>
Use a left outer join in FetchXML to query for records "not in"
So explicit link-type='outer' is required for outer join but inner join is default.
Interestingly Fetchxml is full of surprises. You can also refer FetchXML schema
I have to Pull all customers whose ids are in the list
I have a list of CustomerID`s
List custidlist=new List{1,2,3....etc.}();
i have to write a linq query to get all customers whose id`s are in the above list
custidlist.
var customers=db.Customers.Where(c=> custidlist.Contains(c.customerid));
Using Contains is not good in performance issue.
Can we use COMPARE OPERATOR LIKE THIS
var customers=db.Customers.Where(c=> custidlist.Compare(c.customerid)); ????
I Heard Compare is best for Performance
Since this is Linq to SQL / Entities your Linq Contains query will be translated to a SQL statement roughly like:
select * from Customers where customerId in (1,2,3)
Not only is your other suggestion not supported, but also you cannot do any better than this SQL performance wise.
When you write a Contains query in Linq to SQL it iwll be fired as an in query in SQL and running your query on the databse should be the fastest..
one caveats to this though is to remember in query might have a limit on the number of entities I think its around 2000+ in sql server and the way around this would be to batch your query.