Dynamics CRM how to get list of all entities - c#

Working with CRM 2013, how can I get a list of all entities in the CRM via the connectionManager class? I want to get all the entities for the current connection.

Thank you for your comment and answer it work now,
this is my function
public static EntityMetadata[] GetEntities ( IOrganizationService organizationService)
{
Dictionary<string, string> attributesData = new Dictionary<string, string>();
RetrieveAllEntitiesRequest metaDataRequest = new RetrieveAllEntitiesRequest();
RetrieveAllEntitiesResponse metaDataResponse = new RetrieveAllEntitiesResponse();
metaDataRequest.EntityFilters = EntityFilters.Entity;
// Execute the request.
metaDataResponse = (RetrieveAllEntitiesResponse)organizationService.Execute(metaDataRequest);
var entities = metaDataResponse.EntityMetadata;
return entities;
}
and i call my function in the windows app form like this:
var allEntities = CRMHelpers.GetEntities(service);
foreach (EntityMetadata Entity in allEntities)
{
cbxEntity.Items.Add(Entity.LogicalName);
}

If you are looking for getting the entity metadata using code (C#) then we have inbuilt messages to get all entities and if required attribute level information as well. You can use the message "RetrieveAllEntitiesRequest". A sample code would be as follows to achieve the same.
RetrieveAllEntitiesRequest retrieveAllEntityRequest = new RetrieveAllEntitiesRequest
{
RetrieveAsIfPublished = true,
EntityFilters = EntityFilters.Attributes
};
RetrieveAllEntitiesResponse retrieveAllEntityResponse = (RetrieveAllEntitiesResponse)serviceProxy.Execute(retrieveAllEntityRequest);
If you need to get a specific entity information then you may use the message "RetrieveEntityRequest". A sample for the same would be as follows,
RetrieveEntityRequest entityRequest = new RetrieveEntityRequest
{
EntityFilters = EntityFilters.Attributes,
LogicalName = entityName,
RetrieveAsIfPublished = true
};
RetrieveEntityResponse entityResponse = (RetrieveEntityResponse)serviceProxy.Execute(entityRequest);
Hope this is what you were looking for. Let us know if you need any more information on the same.

Related

Dynamics 365 FakeXrm "usersettings" entity error

I have this piece of code in my Dynamics 365 plugin,
private int? RetrieveCurrentUsersSettings(IOrganizationService service)
{
var currentUserSettings = service.RetrieveMultiple(
new QueryExpression("usersettings")
{
ColumnSet = new ColumnSet("timezonecode"),
Criteria = new FilterExpression
{
Conditions =
{
new ConditionExpression("systemuserid", ConditionOperator.EqualUserId)
}
}
}).Entities[0].ToEntity<Entity>();
return (int?)currentUserSettings.Attributes["timezonecode"];
}
and I am writing a UnitTest for it with FakeXrm, and while debugging I am getting an error, in this query expression.
Here is my fake Xrm code.
Entity systemUser = new Entity("systemuser");
systemUser.Id = Guid.NewGuid();
Entity userSettings = new Entity("usersettings");
userSettings.Id = Guid.NewGuid();
userSettings["timezonecode"] = 71;
userSettings["systemuserid"] = systemUser.ToEntityReference();
fakedContext.Initialize(new List<Entity>()
{
workOrder, owner, invoiceNote, userSettings
});
The question is, how to create usersettings entity in FakeXrm and provide proper attributes to it.
I am glad that you followed my suggestion to ask the question on StackOverflow.
Anyway you should have pointed out that you asked the same question on GitHub on the FakeXrmEasy repository and that the solution was provided there with this answer.
Long story short, the problem with your UnitTest was that you were missing fakedContext.CallerId = systemUser.ToEntityReference(); and that was needed because you were using ConditionOperator.EqualUserIdin your query.
Best Regards, Betim Beja.
I have found a solution
Entity systemUser = new Entity("systemuser");
systemUser.Id = Guid.NewGuid();
fakedContext.CallerId = systemUser.ToEntityReference();
IOrganizationService service = fakedContext.GetOrganizationService();
Entity userSettings = new Entity("usersettings");
userSettings.Id = Guid.NewGuid();
userSettings["timezonecode"] = 71;
userSettings["systemuserid"] = systemUser.ToEntityReference();

Get Share Account privileged account entities in CRM sdk

I have been wondering that how we could query to get list of Accounts which is Shared for a user. By using SDK I have tried the following methods but could not able to find out the proper solution:
QueryExpression query1 = new QueryExpression
{
EntityName = "account",
ColumnSet = new ColumnSet("name", "address1_city")
};
query1.LinkEntities.Add(new LinkEntity("account", "systemuser", "ownerid", "systemuserid", JoinOperator.Inner));
query1.LinkEntities[0].Columns.AddColumns("fullname");
query1.LinkEntities[0].EntityAlias = "share";
I am new to CRM sdk working my head around this the whole day.
Can anyone please help?
Try using a RetrieveSharedPrincipalsAndAccessRequest.
MSDN.
var accessRequest = new RetrieveSharedPrincipalsAndAccessRequest
{
Target = leadReference
};
// The RetrieveSharedPrincipalsAndAccessResponse returns an entity reference
// that has a LogicalName of "user" when returning access information for a
// "team."
var accessResponse = (RetrieveSharedPrincipalsAndAccessResponse)_serviceProxy.Execute(accessRequest);
Console.WriteLine("The following have the specified granted access to the lead.");
foreach (var principalAccess in accessResponse.PrincipalAccesses)
{
Console.WriteLine("\t{0}:\r\n\t\t{1}", GetEntityReferenceString(principalAccess.Principal), principalAccess.AccessMask);
}

create a new record in service entity

I have seen example of creating Accounts Entity records, Contacts entity records through C#, i wanted to know how do we create a service record in CRM through C#(.net) code.
Eg: We already have "Plumbing service" record in service entity view. So i wanted to create a new record in service entity through C# code (early or late binding doesn't matter).
Can someone help me on this with code.
Quite some XML is required when creating this Services from code. Additionally, before you can create a Service you will need to create a ResourceSpec and a ConstraintBasedGroup.
First create a ConstraintBasedGroup:
var bu = context.BusinessUnitSet.First().ToEntityReference();
var cbg = new ConstraintBasedGroup
{
BusinessUnitId = bu,
Name = "CBG1",
Constraints = "<Constraints><Constraint><Expression><Body>false</Body><Parameters><Parameter name=\"resource\"/></Parameters></Expression></Constraint></Constraints>"
};
var cbgId = OrganizationService.Create(cbg);
Then create a ResourceSpec:
var resSpec = new ResourceSpec
{
BusinessUnitId = bu,
Name = "RS1",
RequiredCount = 1,
ObjectiveExpression = "<Expression><Body>udf\"Random\"(factory,resource,appointment,request,leftoffset,rightoffset)</Body><Parameters><Parameter name=\"factory\"/><Parameter name=\"resource\"/><Parameter name=\"appointment\"/><Parameter name=\"request\"/><Parameter name=\"leftoffset\"/><Parameter name=\"rightoffset\"/></Parameters><Properties EvaluationInterval=\"P0D\" evaluationcost=\"0\"/></Expression>",
GroupObjectId = cbgId
};
var resSpecId = OrganizationService.Create(resSpec);
And finally, you can create your Service:
var svc = new Service
{
Name = "Service1",
Granularity = "FREQ=MINUTELY;INTERVAL=15",
ResourceSpecId = new EntityReference(ResourceSpec.EntityLogicalName, resSpecId),
InitialStatusCode = new OptionSetValue(0),
Duration = 15
};
OrganizationService.Create(svc);
I would suggest you create similar things using the UI of CRM in case you are wondering about the specific formats of the XML you require. The XML I used in my examples is pretty much the default XML CRM generates.

Create ActivityParty in CRM without early bound Entities

As a requirement I cannot use the early bound context created with "CrmSvcUtil". The problem is that a new phonecall activity expects two fields ('from' and 'to') which are Entities of type activityparty. The standard XRM/CRM namespace does not contain a class similar to ActivityParty created with the Utility.
I tried filling it with an EntityCollection but then the field will be empty. Next I tried to recreate the structure of a working phonecall activity. EntityCollection "activityparty" -> with one Entity "activityparty" -> with EntityReference attribute "partyid" -> the entity ref (e.g. "contact" and the contact's id). But it simply does not work.
How can I create an ActivityParty (or better a phonecall Activity) with the "normal" Entitiy classes?
If I'm right you don't need to use an EntityCollection but an array of Entity
To create a phone call with late bound syntax will be:
Entity from1 = new Entity("activityparty");
Entity to1 = new Entity("activityparty");
Entity to2 = new Entity("activityparty"); // two contacts inside the to field
from1["partyid"]= new EntityReference("systemuser", userId);
to1["partyid"]= new EntityReference("contact", contact1Id);
to2["partyid"]= new EntityReference("contact", contact2Id);
Entity phonecall = new Entity("phonecall");
phonecall["from"] = new Entity[] { from1 };
phonecall["to"] = new Entity[] { to1, to2 };
// other phonecall fields
Guid phonecallId = service.Create(phonecall);
Even though I upvoted the answer but I had simmilar problem with serialization of ActivityParty. I came to solution that doesn't require you to give up on early bound entities.
what you need to do is something like this:
IEnumerable<ActivityParty> party = new [] { new ActivityParty { PartyId="", EntityLogicalName="..." } };
phonecall["to"] = new EntityCollection(party.Select(x => x.ToEntity<Entity>).ToList());
(I didn't test the code and wrote it from the air but you should feel the idea)
I vote for TrN because i was looking for any kind of example, and it's the only early bound example that i could find.
His example Actually helped me create an PhoneCall entity that had the Attribute "From" pointing to the Lead that actually made the call. I never fully understood the IEnumerable<ActivityParty> enumerator. Thanks to TrN i understand it enough to use it.
Here is my code regarding the PhoneCall activity that I've tested and it works. Everytime an existing Lead calls. The PhoneCall activity gets saved with the correct Attribute values linked to the correct Lead.
IEnumerable<ActivityParty> party = new[] { new ActivityParty { LogicalName = ActivityParty.EntityLogicalName , PartyId = eref2 } };
Console.WriteLine("Logging activity to {0}", firstName);
Console.WriteLine("... \n" );
PhoneCall newCall = new PhoneCall { Description = "Missed phone call from this lead", DirectionCode = true, RegardingObjectId = eref2,
Subject = "Missed Call", PhoneNumber = MissedCall, OwnerId = User, From = party };
Guid newCallId = service.Create(newCall);
Console.WriteLine("Log successfully created \n \n ");
As i said, For Kirschi this isnt the real solution given his requirement of not having any context. But anyone who wants/can use provided context and is curious how the IEnumerable<ActivityParty> works, this might help them to create a proper PhoneCall Activity.
Here is working code for the same. Feel free to reach out if anyone faces any issue.
private static void fetchRelatedPhoneCalls(IPluginExecutionContext context, IOrganizationService service, Guid yourGuid, Entity opp)
{
string strFetchPhoneCalls = string.Format(FetchQuery.bringFetchQueryForPhoneCalls(),yourGuid);
EntityCollection entPhoneCalls = (EntityCollection)service.RetrieveMultiple(new FetchExpression(strFetchPhoneCalls));
if (entPhoneCalls != null && entPhoneCalls.Entities.Count > 0)
{
for (int i = 0; i < entPhoneCalls.Entities.Count; i++)
{
Entity entPhoneCall = (Entity)entPhoneCalls.Entities[i];
string[] strAttributesPCtoRemove = new string[] { "createdon", "createdbyname", "createdby"
,"modifiedon", "modifiedby" ,"regardingobjectid","owninguser"
,"activityid", "instancetypecode", "activitytypecode" // PhoneCall Skip
};
Entity entNewPhoneCall = this.CloneRecordForEntity("phonecall", entPhoneCall, strAttributesPCtoRemove);
entNewPhoneCall["regardingobjectid"] = new EntityReference(context.PrimaryEntityName, context.PrimaryEntityId);
entNewPhoneCall["to"] = this.getActivityObject(entNewPhoneCall, "to");
entNewPhoneCall["from"] = this.getActivityObject(entNewPhoneCall, "from");
service.Create(entNewPhoneCall);
}
}
}
private static Entity CloneRecordForEntity(string targetEntityName, Entity sourceEntity, string[] strAttributestoRemove)
{
Entity clonedEntity = new Entity(targetEntityName);
AttributeCollection attributeKeys = sourceEntity.Attributes;
foreach (string key in attributeKeys.Keys)
{
if (Array.IndexOf(strAttributestoRemove, key) == -1)
{
if (!clonedEntity.Contains(key))
{
clonedEntity[key] = sourceEntity[key];
}
}
}
return clonedEntity;
}
private static EntityCollection getActivityObject(Entity entNewActivity, string activityFieldName)
{
Entity partyToFrom = new Entity("activityparty");
partyToFrom["partyid"] = ((EntityReference)((EntityCollection)entNewActivity[activityFieldName]).Entities[0].Attributes["partyid"]);
EntityCollection toFrom = new EntityCollection();
toFrom.Entities.Add(partyToFrom);
return toFrom;
}

linq to sql one-one relationship C#

It is necessary that after the creation of records in the table "Clients" took up ID. Later ID used to create a new entry in the "Clients_details".
var user = GetUsers();
var userdet = GetclientsDetails();
string hashedpass = getMd5Hash(UIPassword.Text);
var newreg = new Clients
{
login = UILogin.Text,
password = hashedpass,
subscribeid = Convert.ToInt32(UIId.Text)
};
user.InsertOnSubmit(newreg);
user.Context.SubmitChanges();
var details = new Clients_details
{
city = UICity.Text,
first_name = UIFirst_name.Text,
last_name = UIFamiliya.Text,
name = UIName.Text,
Clients = newreg
};
userdet.InsertOnSubmit(details);
userdet.Context.SubmitChanges();
After this code fails:
"An attempt was made to perform an operation Attach or Add in relation to an object that is not new, and possibly loaded from another DataContext. This operation is not supported."
How to properly create a record that does not appear a mistake? Thank you!
private static Table<Clients> GetUsers()
{
var dce = new BaseDBMLDataContext();
return dce.Clients;
}
private static Table<Clients_details> GetclientsDetails()
{
var dce = new BaseDBMLDataContext();
return dce.Clients_details;
}
Looks like userdet.Context and user.Context was built using a different dataContext and that needs to be created using the same dataContext rather than instantiating a new one.
I think you need to only call the SubmitChanges only once in the end, and also you need to make sure the user and userdet you are using share the same context
As the error clearly states, you're using different contexts (user and userdet) for each entity to add. You should have one DataContext and use that one to add the entities.
Yes looks like you're using two different instances of the same context:
user.Context.SubmitChanges();
userdet.Context.SubmitChanges();
A good approach to build up your entities should be something like :
//Create your client details entity
var details = new Clients_details
{
city = UICity.Text,
first_name = UIFirst_name.Text,
last_name = UIFamiliya.Text,
name = UIName.Text
};
//Create your client entity
var newreg = new Clients
{
login = UILogin.Text,
password = hashedpass,
subscribeid = Convert.ToInt32(UIId.Text),
//Assigning the details entity (FK) to the client
ClientDetails = details
};
//Saving both the client and its details
user.InsertOnSubmit(newreg);
user.Context.SubmitChanges();

Categories