Resolve entity id to entity type in MS Dynamics CRM - dynamics-crm-2011

Do you know is there any like a global reference book of MS CRM entities in the system?
I need to resolve entity id to the entity type without checking every single entity for presence of given GUID.
Is it possible?

I don't know of any supported way, but I believe you could to a SQL query on the PrincipalObjectAccess table in the database and retrieve the value of ObjectTypeCode where ObjectId is the GUID.

For annotation you need to look at the field objecttypecode to determine the entity type of objectid.
You can either generate a list of entity logical names and object type codes in your code as a Dictionary object (this will give you the fastest performance but requires you know all the entity types that will be in the system at the time you compile) or (if you are on CRM 2011 UR12+ or CRM 2013) you can do a MetadataQuery.
You can read more about doing a metadata query here: http://bingsoft.wordpress.com/2013/01/11/crm-2011-metadata-query-enhancements/
Sample code for your requirement:
var objTypeCode = [INTEGER] //Make this this the annotation.objecttypecode
MetadataFilterExpression entityFilter = new MetadataFilterExpression(LogicalOperator.And);
EntityFilter.Conditions.Add(new MetadataConditionExpression("ObjectTypeCode", MetadataConditionOperator.Equals, objTypeCode);
EntityQueryExpression entityQueryExpression = new EntityQueryExpression()
{
Criteria = entityFilter
};
RetrieveMetadataChangesRequest retrieveMetadataChangesRequest = new RetrieveMetadataChangesRequest()
{
Query = entityQueryExpression,
ClientVersionStamp = null
};
RetrieveMetadataChangesResponse response = (RetrieveMetadataChangesResponse)orgService.Execute(retrieveMetadataChangesRequest);
You can reduce the metadata retrieved, for better performance, as shown here: How to get the CRM Entity Name from the Object Type Code of a RegardingID?

Related

In a master detail relationship how to get a list of master entities without detail entities crm 2011?

I'm using CRM 2011 and I have a 1-n relationship between EntityA(master) and EntityB(detail).
I need to get the list of EntityA records that are not related to any EntityB records. How can I accomplish this inside a plugin using query expression?
I believe this should work (See the EDIT, it doesn't work):
var qe = new QueryExpression("entitya");
var entityBLink = qe.AddLink("entityb", "entityaid", "entityaid", JoinOperator.LeftOuter);
entityBLink.LinkCriteria.AddCondition("entitybid", ConditionOperator.Null);
It should create a SQL Statement that looks something like this:
SELECT
FROM entitya
LEFT OUTER JOIN entityb on entitya.entityaid = entityb.entityaid
AND ( entityb.entitybid IS NULL )
EDIT - Working version
var qe = new QueryExpression("entitya");
var entityBLink = qe.AddLink("entityb", "entityaid", "entityaid", JoinOperator.LeftOuter);
entityBLink.Columns.AddColumn("entitybid");
var entities = service.RetrieveMultiple(qe).Entities.
Where(e => !e.Attributes.Keys.Any(k => k.EndsWith(".entitybid"))).
Select(e => e.ToEntity<entitya>());
The SQL statement for the first query does get generated as is, but since the null check is on the join and it is a left join, all EnityA entities get returned.
The bad news is in CRM there is no way to perform a sub query, or specify in the where clause, a linked entity's properties. I really hope Microsoft spends some time with the next major release adding this type of functionality.
You can however perform the filter on the client side, which is what the C# code is doing above.

Retrieving Properties from DbSqlQuery

Background: Project is a Data Import utility for importing data from tsv files into a EF5 DB through DbContext.
Problem: I need to do a lookup for ForeignKeys while doing the import. I have a way to do that but the retrieval if the ID is not functioning.
So I have a TSV file example will be
Code Name MyFKTableId
codevalue namevalue select * from MyFKTable where Code = 'SE'
So when I process the file and Find a '...Id' column I know I need to do a lookup to find the FK The '...' is always the entity type so this is super simple. The problem I have is that I don't have access to the properties of the results of foundEntity
string childEntity = column.Substring(0, column.Length - 2);
DbEntityEntry recordType = myContext.Entry(childEntity.GetEntityOfReflectedType());
DbSqlQuery foundEntity = myContext.Set(recordType.Entity.GetType()).SqlQuery(dr[column])
Any suggestion would be appreciated. I need to keep this generic so we can't use known type casting. The Id Property accessible from IBaseEntity so I can cast that, but all other entity types must be not be fixed
Note: The SQL in the MyFKTableId value is not a requirement. If there is a better option allowing to get away from SqlQuery() I would be open to suggestions.
SOLVED:
Ok What I did was create a Class called IdClass that only has a Guid Property for Id. Modified my sql to only return the Id. Then implemented the SqlQuery(sql) call on the Database rather than the Set([Type]).SqlQuery(sql) like so.
IdClass x = ImportFactory.AuthoringContext.Database.SqlQuery<IdClass>(sql).FirstOrDefault();
SOLVED:
Ok What I did was create a Class called IdClass that only has a Guid Property for Id. Modified my sql to only return the Id. Then implemented the SqlQuery(sql) call on the Database rather than the Set([Type]).SqlQuery(sql) like so.
IdClass x = ImportFactory.AuthoringContext.Database.SqlQuery<IdClass>(sql).FirstOrDefault();

Access detail element of a collection inside a section in openxava

How can I access the details element of a collection entity which is inside one section of another entity with openxava? For example, in the view of entity A, we have section {S1,S2,S3} and inside section S3 view, we have {collection of entity B}. Now I want to access the detail element of entity B, so that i can fill the element in an action controller. How do I do that?
Get the collection directly from the view, in this way:
Collection myCollection = getView().getSubview("myCollection").getCollectionObjects();
It must work even with oldest OpenXava versions
Obtain the entity associated to the view and get the collection from it. Since OpenXava 4.3 you can do it in this way:
MyEntity myEntity = (MyEntity) getView().getEntity();
Collection myCollection = myEntity.getMyCollection();
If you're using an OX previous to 4.3 do it in this way:
Map keyValues = getView().getKeyValuesWithValue();
if (!keyValues.isEmpty()) {
MyEntity myEntity = (MyEntity)
MapFacade.findEntity(getView().getModelName(), keyValues);
Collection myCollection = myEntity.getMyCollection();
}
You can do it in several ways. Here you have one, I have used it with some references that I want to modify from inside of an action called by the base module (which should work with your collection):
Query q = XPersistence.getManager().createQuery("JPQL QUERY TO RETRIVE THE COLLECTION WITH :parameterIfNeeded");
q.setParameter("parameterIfNeeded", "value");
List entityBList = q.getResultList();
if (getView().getModelName().equalsIgnoreCase("yourBaseModelViewName")) {
getView().getSubview("yourSubViewName").setModel(entityBList);
getView().getSubview("yourSubViewName").refresh();
}
You must to be using OX 4.6 to be able to use setModel(). And remember that the "yourSubViewName" is the name of the property for your collection into the base model.
I have not tested that code with a collection, so make the adjustments according to your needs, maybe you will need to CAST the query result list or something.

Sharepoint 2010 Metadata fields Key, Value

I'm currently working with Sharepoint 2010 and Sharepoint API on creating a document library with some existing document lists.
I have created a WinForm that loops through a given doc lists and then add them to diffrent document libraries depending on 'Type(A metadata field)' of the document. Type is determined by reading the "Metadata fields" for the specific document. Metadata fields are read by creating Hashtable of SPFields
Question
When document metadata field is read to determin the 'Type', I have realised that the Metadatafield 'Type'(Key) actually pulls out as 'Type+TaxHTField0' and value for the Key pulls out as value|GUID
So for example if my Metadata field is called Doc_x0020_Type when it returns from the API it comes out as Doc_x0020_TypeTaxHTField0 the value for this should be just 'products' but it comes out as
products|21EC2020-3AEA-1069-A2DD-08002B30309D
Is there a setting we can set in sharepoint to eleminate adding extra charaters and GUID to both Key and Value for metadata fields?
Below is what I've done to rectify the issue, but wondered if it's a setting we can set in sharepoint
public String GetLibrary(Hashtable itemProperties)
{
String typeMetaField = "Doc_x0020_TypeTaxHTField0";
String sKey = String.Empty;
foreach (DictionaryEntry deEntry in itemProperties)
{
sKey = deEntry.Key.ToString();
if (sKey == typeMetaField){
_type = deEntry.Value.ToString();
string[] value = _type.Split('|');
_type = value[0].Trim();
}
}
return GetDocumentLibrary(_type);
}
This is by design.
If you add a taxonomy field to your own contenttype (for instance named 'MyTaxField') SharePoint will autogenerate a hidden 'Notes' field that contains the label and the guid of the values you select in the UI.
This is quite helpful when using SPSiteDataQuery since it will return empty values for taxonomy fields that allow multiple values (works with single value taxonomy fields though).
The only way to get the taxonomy values is to have a for the hidden field named 'MyTaxFieldTaxHTField0'.
But as you have discovered, this field might not be formatted as youd like :).
I have not tested this, but did you check if your contenttype contains a field called "Doc_x0020_Type" (possible of type TaxonomyFieldValue(Collection))?

Query on object id in VQL

I'm currently working with the versant object database (using jvi), and have a case where I need to query the database based on an object id.
The problem is I'm running some performance tests on the database using the pole position framework, and one of the tests in that framework requires me to fetch an object from the database using either an object reference or a low level object id. Thus, I'm not allowed to reference specific fields in the employee object, but must perform the query on the object in its entirety. So, it's not allowed for me to go "select * from Employee e where e.id = 4", I need it to use the entire object.
What I'm trying to achieve is something along the lines of
Employee employee = new Employee("Mr. Pickles");
session.commit();
FundVQLQuery q = new FundVQLQuery(session,
"select * from Employee employee where employee = $1");
q.bind(employee);
q.execute();
However, this throws an EVJ_NOT_A_VALID_KEY_TYPE error. Does anyone know the correct way of doing this?
Sure you figured this out (post was months ago). What you want to do is use the GetObjectId first, to get the VOD Id of the object, then query the DB;
id = session.GetObjectId(employee);
This is how I did the whole roundtrip object → OID → object:
First you get the OID with TransSession.getOidAsLong.
TransSession session = ...;
Employee employee = new Employee("Mr. Pickles");
long oid = TransSession.getOidAsLong(employee);
session.commit();
Once you have the object ID, just grab the object from its Handle.
TransSession session = ...;
Employee employee = (Employee)session.returnHandleFromLong(oid).handleToObject();
No VQL needed.
Usually keys are integers and not strings. You are creating an Employee using just his name, perhaps the correct identifier to use is his employeeId. I need some more information on the table to know for sure.
You can try this,
FundVQLQuery vql = FundVQLQuery (session,
"select selfoid from Employee where name = $1");
vql.bind ("Mr. Pickles");
HandleEnumeration e = vql.execute ();
while ( e.hasmoreHandles() ) {
Handle handle = e.nexthandle();
}
It will return all Employees with the name "Mr. Pickles", Then loop through them.

Resources