EntityReference is not working with AlternateKey - dynamics-crm

I created an alternate key on Contact Entity that name is obs_key.
Here is the screenshot of the key definition.
and then I try to create EntityReference object like below;
string customerCode = entity.GetAttributeValue<string>("obs_customer_code");
EntityReference contactRef = new EntityReference("contact", "obs_key", customerCode);
But I'm getting errors. Error says
Invalid EntityKey Operation performed : Entity contact does not
contain an attribute named obs_key
How can I fix the problem?

Microsoft's documentation says you need to set keyname and keyvalue like below.
public EntityReference (string logicalName, string keyName, object keyValue);
Documentation Link
My alternate key name is : obs_key
the field dependent with alternate key : obs_id
But it didn't work. I try to set the field name, not the key name and it works.
EntityReference contactRef = new EntityReference("contact", "obs_id", customerCode);

Related

Dynamics 365 API link between ActivityPointer and activitytypecode global option set

I am reading data from the ActivityPointer entity in Dynamics 365 via the API and I want to link the activitytypecode field value to the activitypointer_activitytypecode global option set, which I believe is the correct one. However the values don't seem to match. In the ActivityPointer.activitytypecode field I have values such as:
phonecall
bulkoperation
email
appointment
task
But those values don't appear in the option set definition, using this query: GlobalOptionSetDefinitions(Name='activitypointer_activitytypecode')
The option set has the code values (e.g. 4202 for Email) and the different descriptions in all languages, but nothing matches back to the values on ActivityPointer
Optionset is just key value pairs (4202: Email and so on), If you want to get the formatted text value of optionset (Email, Fax, etc) from your web api query results - then you have to use activitytypecode#OData.Community.Display.V1.FormattedValue to get it. Read more
I recommend this article for complete understanding of CRM activities.
If you are looking for the code integer value in your resultset, that seems to be an issue and the result is not the expected one - old SO thread
The problem is that if you are reading activitytypecode in code, then you will know that you get a string value. This is the logical name of the activity entity, e.g. "email", "phonecall" etc.
If you look at the definition of activitytypecode in Power Apps then it shows it as "Entity name" (i.e. text) but using the classic solution editor it shows as the global activitypointer_activitytypecode option set, which contains values for "Email", "Phone Call" etc.
I am sure that there should be a simple way of converting from activitytypecode (i.e. entity name) to activitypointer_activitytypecode (i.e. option set), but I've yet to find it.
What I am doing is retrieving the global activitypointer_activitytypecode option set, so I have access to all of the text values. Then retrieve details about the entity indicated by activitytypecode, specifically what is of interesting is the display name. Then loop through the option set looking for a case-insensitive match on display name.
This is my C# code:
public int? GetActivityType(IOrganizationService service, string activityTypeCode)
{
// Get all activity types.
var optionSetRequest = new RetrieveOptionSetRequest()
{
Name = "activitypointer_activitytypecode"
};
var optionSetResponse = (RetrieveOptionSetResponse)service.Execute(optionSetRequest);
var optionSetMetadata = (OptionSetMetadata)optionSetResponse.OptionSetMetadata;
var optionValues = new Dictionary<string, int?>(StringComparer.OrdinalIgnoreCase);
foreach (var option in optionSetMetadata.Options)
{
foreach (var optionLabel in option.Label.LocalizedLabels)
{
optionValues[optionLabel.Label] = option.Value;
}
}
// Get the display name for the activity.
var retrieveEntityRequest = new RetrieveEntityRequest
{
EntityFilters = EntityFilters.Entity,
LogicalName = activityTypeCode
};
var retrieveEntityResponse = (RetrieveEntityResponse)service.Execute(retrieveEntityRequest);
LocalizedLabelCollection entityLabels = retrieveEntityResponse.EntityMetadata.DisplayName.LocalizedLabels;
// Look up the display name in the option set values.
foreach (var entityLabel in entityLabels)
{
if (optionValues.TryGetValue(entityLabel.Label, out int? value))
{
return (Schema.GlobalOptionSet.ActivityType?)value;
}
}
// If we get here then we've failed.
return null;
}
That is making two API calls, so best avoided in any situations where performance might be an issue. I'm not saying the code is perfect, but it hasn't let me down yet. Even so, I would recommend making do with the logical names provided by activitytypecode if you can.

Dynamically pass Type to Method<T>

I've a method , that retrieves to me some data according to some type I passed in parameter, like this :
protected void FillList<TEntity>()
{
doWorkForTEntity();
}
I Need to dynamically call this method :
Type[] entities = System.Reflection.Assembly.GetAssembly(typeof(User)).GetTypes();
Type currentEntity = (from entity in entities
where entity.Name.Equals(this.targetEntity)
select entity).FirstOrDefault();
FillList<currentEntity>();
I got this error :
The type or namespace name 'currentEntity' could not be found (are you missing a using directive or an assembly reference?)
I've tried an intermediate object type, no success
Any Idea please ?
Since there is no information about entity type in compile time, you need to construct and call appropriate method by reflection:
Type[] entities = System.Reflection.Assembly.GetAssembly(typeof(User)).GetTypes();
Type currentEntity = (from entity in entities
where entity.Name.Equals(this.targetEntity)
select entity).FirstOrDefault();
var method = this.GetType().GetMethod("FillList", BindingFlags.Instance | BindingFlags.NonPublic)
.MakeGenericMethod(currentEntity);
method.Invoke(this, new object[0]);
You need to do that with reflection as well, so it won't fail in compile time (compiler checks):
Generic class:
Type[] entities = System.Reflection.Assembly.GetAssembly(typeof(User)).GetTypes();
Type currentEntity = (from entity in entities
where entity.Name.Equals(this.targetEntity)
select entity).FirstOrDefault();
Type fillListType= typeof(FillList<>);
Type constructedGenericClass = fillListType.MakeGenericType(currentEntity);
object myList = Activator.CreateInstance(constructedGenericClass );
Generic Method:
Type[] entities = System.Reflection.Assembly.GetAssembly(typeof(User)).GetTypes();
Type currentEntity = (from entity in entities
where entity.Name.Equals(this.targetEntity)
select entity).FirstOrDefault();
MethodInfo methodinfo = this.GetType().GetMethod("FillList");
MethodInfo genericMethod = method.MakeGenericMethod(currentEntity);
genericMethod.Invoke(this, null);
Type parameters must be specified at compile time and can´t be assigned at runtime like in your example. You get the error message because there´s no Type called currentEntiry since it´s just a variable.
Change your method to take an instance of the Type TEntity:
protected void FillList<TEntity>(TEntity instance)
{
doWorkForTEntity();
}
Create a dynamic instance from the Type name and then call the modified method:
dynamic instance = Activator.CreateInstance(this.targetEntity);
FillList(instance);
The dynamic type is basically doing what the other answers have shown you - but IMHO this code is neater and clearer in its intent.

how can i get the values of the current item in sharepoint 2010

I have a list(registration) with fields like username,pwd ,name,age etc.
i want to send a mail to admin with all the fields (username,pwd,age etc...) when a new item is added to the custom list.i tried by using added event but i am unable to get the values of the newly added item.
it is entering into the if loop but at the next line i am getting an error object reference not set to any instance.
Thanks in advance
i am new to SharePoint
public override void ItemAdded(SPItemEventProperties properties)
{
base.ItemAdded(properties);
SPWeb oSPWeb = properties.OpenWeb();
//GETTING THE LIST NAME
String curListName = properties.ListTitle;
if (curListName == "registrtion")
{
//FETCH THE DATA OF THE NEW ADDED ITEM IN THE LIST
string EMPLOYEENAME = properties.AfterProperties["EMPLOYEENAME"].ToString();
}
}
Use this instead:
string EMPLOYEENAME = properties.ListItem["InternalFieldName"]
Make sure you use the internal name of the field, check here how to get that name:
http://sharepoint-works.blogspot.com.au/2012/06/internal-column-name-in-sharepoint-list.html

ef4 poco,how get id after insert?

I am inserting a document and i want references id of document to a part of this
document...but the code is autoincrement, and i am using poco. how i can get
back the code of insert file?
ArquivoDTO file = new ArquivoDTO();
file.NomeArquivo = fileName;
file.TipoArquivo = fileType;
file.TamanhoArquivo = fileSize;
var context = new PROGISContext();
ArquivoRepository arquivoRepository = new ArquivoRepository(context);
arquivoRepository.IncluirArquivo(file); //insert file
ParteArquivoDTO part = new ParteArquivoDTO(); //create a part
part.CodArquivo = file.CodArquivo; // here id of inserted file
Something like this
[Key, DatabaseGenerated( DatabaseGeneratedOption.Identity )]
public Guid Identifier { get; protected set; }
However you won't get the I'd untill you call SaveChanges()
It's kind of hard to say what's the problem with this code sample alone, but are you calling SubmitChanges() on your DataContext in arquivoRepository.IncluirArquivo(file)?
If you are, and the CodArquivo property of your ArquivoDTO class it correctly configured to be an auto increment ID, then the property should get updated automatically after SubmitChanges().

Find items is SSRS by Id

How do you find items in SSRS by ID? I tried to use the id returned by another find result, a new guid to string and small random string all of which return the same error:
The ID field has a value that is not valid. ---> Microsoft.ReportingServices.Diagnostics.Utilities.InvalidElementException: The ID field has a value that is not valid.
Here is the code:
var request = new FindItemsRequest
{
Conditions = new[] { new SearchCondition { Name = "ID", Value = "test"} },
Folder = "/"
};
return _ssrsService
.FindItems(request)
.Items
I'm using SSRS 2005.
Pretty sure this can't be done through the SSRS service. Ended up finding all objects then using LINQ to filter down to the ID I need.
The MS documentation on the FindItems method says:
Applications that use FindItems typically accept user input for specific properties and property values. The searchable properties are Name, Description, CreatedBy, CreationDate, ModifiedBy, and ModifiedDate. The items that are returned are only those for which a user has Read Properties permission.

Resources