Reputation: 3565
I'm developing a survey module for CRM 2011, where a CRM user can make a survey with multiple questions of different types and ask contacts to answer them using a dynamic web page on Azure. I have completed about 90% of it so far and just need to add a few minor changes involving data management.
The part I'm currently optimizing involves sorting my questions. I have 2 entities in CRM: surveyquestion and question. question refers to an actual question in the survey, while surveyquestion is an N-N relationship entity with a few additional fields, so we can reuse questions in different surveys. I have a field "groep" in "question" which is used to indicate whether a question should be grouped with another question on the form. I have another field, "volgorde" in "surveyquestion", which is used to indicate the order of the questions. I wish to show all questions with the same "group" together, and then order any questions inside groups (and ungrouped questions as a separate group) by the sortorder field. So I basically need to order on 2 fields in 2 different tables, which seems to be quite tricky.
This is the code I'm currently using. I'm getting a nullreferenceexception on the join for vraaglist, which is weird because both vr.Id and ev.slfn_vraag.Id have data in the relevant rows. I don't think it's due to the orderby, because the commented code above works (but I cannot simply add ev.volgorde to my orderby because he complains about that.
public List<slfn_vraag> GetVragenforEnquete(Guid enGuid)
{
//List<slfn_vraag> vraaglist = (from vr in _oContext.slfn_vraagSet
// join ev in _oContext.slfn_enquetevraagSet on vr.Id equals ev.slfn_vraag.Id
// orderby vr.slfn_Groep
// where ev.slfn_enquete.Id == enGuid
// select vr).ToList();
IQueryable<slfn_enquetevraag> enquetevraaglist = (from ev in _oContext.slfn_enquetevraagSet
orderby ev.slfn_volgorde
where ev.slfn_enquete.Id == enGuid
select ev);
List<slfn_vraag> vraaglist = (from vr in _oContext.slfn_vraagSet
join ev in enquetevraaglist on vr.Id equals ev.slfn_vraag.Id
orderby vr.slfn_Groep
select vr).ToList();
return vraaglist;
}
The code compiles without errors, but when i run it, I get a NullReferenceException on the question query. does anyone have any ideas on how to fix this?
edit: exception details from VS2012 as requested below.
System.NullReferenceException occurred
HResult=-2147467261
Message=De objectverwijzing is niet op een exemplaar van een object ingesteld.
Source=Microsoft.Xrm.Sdk
StackTrace:
bij Microsoft.Xrm.Sdk.Linq.QueryProvider.TranslateJoin(QueryExpression qe, IList`1 methods, Int32& i, Projection& projection, List`1& linkLookups)
bij Microsoft.Xrm.Sdk.Linq.QueryProvider.GetQueryExpression(Expression expression, Boolean& throwIfSequenceIsEmpty, Boolean& throwIfSequenceNotSingle, Projection& projection, NavigationSource& source, List`1& linkLookups)
bij Microsoft.Xrm.Sdk.Linq.QueryProvider.Execute[TElement](Expression expression)
bij Microsoft.Xrm.Sdk.Linq.QueryProvider.GetEnumerator[TElement](Expression expression)
bij Microsoft.Xrm.Sdk.Linq.Query`1.GetEnumerator()
bij System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
bij System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
bij Enquete_Webform.Data.EnqueteGenerator.GetVragenforEnquete(Guid enGuid) in e:\VS\tfs_products\MS CRM\2011\Enquete\Enquete_Webform\Enquete_Webform\Data\EnqueteGenerator.cs:regel 49
InnerException:
Upvotes: 0
Views: 1945
Reputation: 3565
After reading Daryl's comment about FetchXML, I've decided to convert my LINQ query to FetchXML, because this does support linked entity sorting. It now works as it should, and I get the results I need.
for completion, this is the fetchXML I ended up using:
<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true'>
<entity name='slfn_vraag'>
<attribute name='slfn_vraagid' />
<attribute name='slfn_vraag' />
<attribute name='slfn_typevraag' />
<attribute name='slfn_groep' />
<order attribute='slfn_groep' descending='false' />
<link-entity name='slfn_enquetevraag' from='slfn_vraag' to='slfn_vraagid' alias='aa'>
<attribute name='slfn_volgorde'/>
<order attribute='slfn_volgorde' descending='false' />
<filter type='and'>
<condition attribute='slfn_enquete' operator='eq' value='" + enGuid+@"' />
</filter>
</link-entity>
</entity>
</fetch>
As an aside, None of the fields could be empty, because they were all primary and foreign keys in CRM, linking to other entities.
Upvotes: 1
Reputation: 18895
I'm guessing you have an ev.slfn_vraag that is null. Try adding a where statement to exclude those that have a null value
List<slfn_vraag> vraaglist = (from vr in _oContext.slfn_vraagSet
join ev in enquetevraaglist on vr.Id equals ev.slfn_vraag.Id
where ev.slfn_vragg.Id != null
orderby vr.slfn_Groep
select vr).ToList();
You could also have the null in the first statement as well:
var enquetevraaglist = (from ev in _oContext.slfn_enquetevraagSet
orderby ev.slfn_volgorde
where ev.slfn_enquete != null && ev.slfn_enquete.Id == enGuid
select ev)
I've created an extension method on the Entity Reference class that allows for nulls without erroring.
/// <summary>
/// Returns the Id of the entity reference or Guid.Empty if it is null"
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public static Guid GetIdOrDefault(this EntityReference entity)
{
if (entity == null)
{
return Guid.Empty;
}
else
{
return entity.Id;
}
}
And as far as your question about sorting, CRM doesn't support sorting by a linked field, just keep that in mind.
Upvotes: 1
Reputation: 2571
Enumerable.OrderBy and Enumerable.ThenBy applied to the final vraaglist
, might offer a solution to your case.
Upvotes: 1