I'm a new developer who needs help with a SOQL query. As you know, the standard files and notes related lists on an Account do not include files/notes added on child objects (e.g., Opportunity, Contact, etc.). I have a requirement to create an LWC related list which does include the Account and child objects' files/notes.
I have created an apex class with queries that accomplish this requirement. However, I can't figure out who to include the linkedentityid in the query on the contentversion. I know there are limitations with querying the contentdocumentlink and displaying on the contentversion. Does anyone know how to include the linkedentityid? Basically, the request is to show the file/note and the record where it is related.
Thank you so much for the time and assistance!
public without sharing class FilesRelatedList {
@AuraEnabled(cacheable = true)
public Static List<ContentVersion> cvRecords(String recId){
//Create variable to hold Ids of Account and related Contacts, Asks, Tasks and Drive Opps
set<Id> setIds = new Set<id>();
//Retrive Ids of Account and related Contacts, Asks, Drive Opps and Tasks
list<Account> lstAccount = [SELECT Id FROM Account WHERE Id = :recId];
list<Contact> lstContact = [SELECT Id FROM Contact WHERE AccountId = :recId];
list<Opportunity> lstOpportunity =[SELECT Id FROM Opportunity WHERE AccountId = :recId];
list<Drive_Opportunity__c> lstDriveOpp =[SELECT Id FROM Drive_Opportunity__c WHERE Account__c = :recId];
list<Task> lstTask = [SELECT Id, WhoId, WhatId FROM Task WHERE WhatId = :recId OR WhatId IN :lstOpportunity
OR WhatId IN :lstDriveOpp OR WhoId IN :lstContact];
//Add the Ids from the above to the setIds variable
for(Account acc : lstAccount){
setIds.add(acc.Id);}
for(Contact con : lstContact){
setIds.add(con.Id);}
for(Opportunity opp : lstOpportunity){
setIds.add(opp.Id);}
for(Drive_Opportunity__c driveopp : lstDriveOpp){
setIds.add(driveopp.Id);}
for(Task tsk : lstTask){
setIds.add(tsk.Id);}
//Retrieve all ContentDocumentLinks with a LinkedEntityId matching any Id in the setIds variable above
List<ContentDocumentLink> files = [SELECT ContentDocumentId, LinkedEntityId, ContentDocument.LatestPublishedVersionId,
ContentDocument.FileExtension, ContentDocument.Title, ContentDocument.ContentModifiedDate, LinkedEntity.Name,
ContentDocument.OwnerId, ContentDocument.Owner.FirstName, ContentDocument.Owner.LastName
FROM ContentDocumentLink WHERE LinkedEntityId = :setIds];
return files;
}
}
Best Answer
I think you have 2 main options here:
instead of showing a list of ContentVersion, create a wrapper class in which you combine data from ContentDocumentLink and ContentVersion. Basically build a Map<Id,WrapperClass> where the Id is the ContentDocumentId. You then populate the records in the map while going through the results of the 2 queries.
make use of the lesser-known 'LatestPublishedVersion' relationship on the ContentDocument object when querying the ContentDocumentLink. This relationship takes you directly to the latest ContentVersion record for a ContentDocument and it does allow the inclusion of relationship fields.
Example query (to be extended with all further fields you need):
As far as I can assess, option #2 seems the more attractive and less complex one for this case.