Get Marketing list ID by name - c#

I am trying to get the id of a marketing list created in Microsoft Dynamics based on the list's name. I will then use the id to add crm contacts to the list (this I can do fine using the id of the list)
I can't find any instructions in the documentation that explains how to do this. I have tried the following code but i get the error that no entity by that name exists:
var request = new RetrieveRequest();
request.Target = new EntityReference("new list 1", listId);
RetrieveResponse response = _organizationService.Execute(request) as RetrieveResponse;
What I am ultimately trying to do is make it possible for an administrator of the crm to identify the marketing list that a user should be added to when they fill in a newsletter form on our website. I think it will be too much to ask them to find the guid of the marketing list (it took me a bit of work to find it myself)
can anyone share some code to either get the id of a list using the list name as the identifier or let me know if its possible to add a contact to a list using the list name instead of the id?

The following code gets all lists in Dynamics with a name of "new list 1". It then stores the Id of the first list returned if one or more matches were found, or Guid.Empty if no matches were found. In your scenario there should be always be one and only one match.
var query = new QueryExpression
{
EntityName = "list",
ColumnSet = new ColumnSet(false)
};
query.Criteria.AddCondition("name", ConditionOperator.Equal, "new list 1";
var matchingLists = _organizationService.RetrieveMultiple(query);
var defaultListId = matchingLists?.Entities.FirstOrDefault()?.Id ?? Guid.Empty;

To retrieve the entity record using RetrieveRequest, schema name of that entity (DB table) should be passed as first parameter and primary key (GUID) as second. For Marketing list it is list & listid. You should also mention ColumnSet.
request.Target = new EntityReference("list", listId);
But to achieve what you want, you have to use either querybyattribute or queryexpression, then RetrieveMultiple will help you to get the Id from name of list.
FilterExpression filter = new FilterExpression();
filter.FilterOperator = LogicalOperator.And;
filter.AddCondition(new ConditionExpression("name", ConditionOperator.Equal, "new list 1"));
QueryExpression query = new QueryExpression("list");
query.Criteria.AddFilter(filter);
var result = Context.SystemService.RetrieveMultiple(query);
After that use AddListMembersListRequest or AddMemberListRequest to add members to that list.
// Add a list of contacts to the marketing list.
var addMemberListReq = new AddListMembersListRequest
{
MemberIds = new[] { _contactIdList[0], _contactIdList[2] },
ListId = listId
};
_serviceProxy.Execute(addMemberListReq);

Related

How can I get all the activities for an account?

I have a program that I have written that gets the data from Dynamics CRM 2013 online. But I am running into one issue where a query to get the activities for an account only returns a subset instead of all the activities. The query expression is this
private QueryExpression CreateActivityQuery(Guid id)
{
QueryExpression query = new QueryExpression()
{
Distinct = true,
EntityName = Cd2Sf.ActivityPointer.EntityLogicalName,
ColumnSet = new ColumnSet(true)
};
query.Criteria = new FilterExpression();
query.Criteria.AddCondition("regardingobjectid", ConditionOperator.Equal, id);
return query;
}
Where the id is the account id. I had first tried using the activityparty where the party id was equal to the account id and then I tried using the regardingobjectid and lastly then tried the Rollup method with the extended related entities but all produce the same result.
#region Create RollupRequest
// Create RollupRequest
RollupRequest rollupRequest = new RollupRequest();
rollupRequest.Query = qexp;
rollupRequest.Target = new EntityReference("account", acct.Id);
rollupRequest.RollupType = RollupType.Extended;
#endregion Create RollupRequest
#region Execute RollupRequest
// Execute RollupRequest
RollupResponse rollupResponse = (RollupResponse)service.Execute(rollupRequest);
#endregion Execute RollupRequest
#region Show RollupResponse results
ShowActivities(rollupResponse.EntityCollection, percent);
#endregion Show RollupResponse results
Do I need to use contacts as well to get all the activities that are associated to the account, i.e. use the activityparty and match the to/from/sender/cc/bcc/etc with contacts for an account? I had tried to use the contact id as the regardingobjectid but that still does not account for all of the activities.
It appears that the web page for dynamics crm online when viewing the account and the activities that are on that page are more than what the above query gets alone.
How do I get the other activities, the ones that seem to be not directly related to the account?
My original answer doesn't answer the question - I've abbreviated it here.
Sarah Champ's post on using outer joins in your fetchxml is really good:
http://blogs.msdn.com/b/crminthefield/archive/2013/07/01/dynamic-activity-reporting-using-fetchxml.aspx
You have to use a FetchExpression rather than a QueryExpression, but you can use it the same way with a RetrieveMultipleRequest now.
FetchExpression example:
string fetch = "<fetch xml string>"
var query = new FetchExpression(fetch);
var request = new RetrieveMultipleRequest();
request.Query = query;
var entities = ((RetrieveMultipleResponse)service.Execute(request)).EntityCollection.Entities;
foreach (var entity in entities)
{
Console.WriteLine(entity.GetAttributeValue<string>("subject"));
}

Retrieve Filter Conditions in Views in CRM 2011 using query expression (C#)

Am developing a windows form which resembles the look up view on CRM 2011.
For this I do the following
1) Show the relevant records (of opportunity entity) in a datagirdview
2) Also have a dropdownlist that binds to the views (View.Name) to allow the user to choose the view according to which i intend to change the filter on my datagrid view.
Am stuck with the following.Am able to retrieve the views on the "Opporutunity" entity using the following code
ConditionExpression condition1 = new ConditionExpression()
{
AttributeName = "querytype",
Operator = ConditionOperator.Equal,
Values = { 0 }
};
ConditionExpression condition2 = new ConditionExpression()
{
AttributeName = "returnedtypecode",
Operator = ConditionOperator.Equal,
Values = { Opportunity.EntityTypeCode }
};
FilterExpression filter = new FilterExpression();
filter.Conditions.Add(condition1);
filter.Conditions.Add(condition2);
QueryExpression queryToRetrieveViews = new QueryExpression
{
ColumnSet = new ColumnSet("savedqueryid", "name", "querytype", "isdefault", "returnedtypecode", "isquickfindquery"),
EntityName = SavedQuery.EntityLogicalName,
Criteria = filter
};
RetrieveMultipleRequest retrieveSavedViewsRequest = new RetrieveMultipleRequest { Query = queryToRetrieveViews };
RetrieveMultipleResponse retrieveSavedViewsResponse = (RetrieveMultipleResponse)crm.Execute(retrieveSavedViewsRequest);
DataCollection<Entity> savedViews = retrieveSavedViewsResponse.EntityCollection.Entities;
foreach (Entity ent in savedViews){...}
I did a quick watch but am unable to find the attribute that has the filter conditions as present in CRM. I mean what i intend to look at is something like this sayfor e.g. open opportunities the filter would be "statecode=0".
Is it possible to fetch the associated filters? -sorry by Associated filters i mean filters of the view
You can filter by whatever attribute you'd like so I'm not sure what you mean by the associated filters. If you mean the filter of the actual view you won't find it. Views are stored in XML, so you'll have to retrieve the the FetchXML for the saved view and parse the XML to see it's filter.

Create a new record with a specific owner without calling AssignRequest in CRM 2011

In our application, we create a few thousand phonecall records. Each phonecall should have a different owner, determined by a method named GetAnyAppropriateSystemUser(), which finds some random SystemUser based on some criteria.
In the code example below, we create a phonecall, and later use AssignRequest on it to specify its owner.
PhoneCall phoneCall = new PhoneCall();
//
// stuff to set up the new PhoneCall instance here; populate fields, etc...
//
// determine this phonecall's owner through some algorithm
Guid appropriateOwner = GetAnyAppropriateSystemUser();
Guid createdPhoneCallId = _serviceProxy.Create(phoneCall);
if (createdPhoneCallId != Guid.Empty)
{
AssignRequest phoneCallAssign = new AssignRequest();
phoneCallAssign.Assignee = new EntityReference(SystemUser.EntityLogicalName, appropriateOwner);
phoneCallAssign.Target = new EntityReference(PhoneCall.EntityLogicalName, createdPhoneCallId);
_serviceProxy.Execute(phoneCallAssign);
}
This works allright, but there are two calls, one to create, and one to assign. Is it ok to just set "ownerid" of the PhoneCall record before calling Create() method, thus eliminating the need to call an AssignRequest later? It seems to work, and I even found an example doing a similar thing in the SDK, as shown below.
SDK Sample: Roll Up Goal Data for a Custom Period Against the Target Revenue
// Create three goals: one parent goal and two child goals.
Goal parentGoal = new Goal()
{
Title = "Parent Goal Example",
RollupOnlyFromChildGoals = true,
ConsiderOnlyGoalOwnersRecords = true,
TargetMoney = new Money(300.0M),
IsFiscalPeriodGoal = false,
MetricId = new EntityReference
{
Id = _metricId,
LogicalName = Metric.EntityLogicalName
},
GoalOwnerId = new EntityReference
{
Id = _salesManagerId,
LogicalName = SystemUser.EntityLogicalName
},
OwnerId = new EntityReference
{
Id = _salesManagerId,
LogicalName = SystemUser.EntityLogicalName
},
GoalStartDate = DateTime.Today.AddDays(-1),
GoalEndDate = DateTime.Today.AddDays(30)
};
_parentGoalId = _serviceProxy.Create(parentGoal);
Although it seems to work, are there anything that we must be aware of if we set ownerid before creating the new record? Are there any differences?
Thank you very much in advance.
As you already found is allowed to set the ownerid when you create the record.
But is not possible to edit the owner of an existing record in the same way, in that case you must use the AssignRequest.
Check also this question:
ETL Software, can't retrieve owner of a contact

How do I order a sql datasource of uniqueidentifiers in Linq by an array of uniqueindentifiers

I have a string list(A) of individualProfileId's (GUID) that can be in any order(used for displaying personal profiles in a specific order based on user input) which is stored as a string due to it being part of the cms functionality.
I also have an asp c# Repeater that uses a LinqDataSource to query against the individual table. This repeater needs to use the ordered list(A) to display the results in the order specified.
Which is what i am having problems with. Does anyone have any ideas?
list(A)
'CD44D9F9-DE88-4BBD-B7A2-41F7A9904DAC',
'7FF2D867-DE88-4549-B5C1-D3C321F8DB9B',
'3FC3DE3F-7ADE-44F1-B17D-23E037130907'
Datasource example
IndividualProfileId Name JobTitle EmailAddress IsEmployee
3FC3DE3F-7ADE-44F1-B17D-23E037130907 Joe Blo Director dsd#ad.com 1
CD44D9F9-DE88-4BBD-B7A2-41F7A9904DAC Maxy Dosh The Boss 1
98AB3AFD-4D4E-4BAF-91CE-A778EB29D959 some one a job 322#wewd.ocm 1
7FF2D867-DE88-4549-B5C1-D3C321F8DB9B Max Walsh CEO 1
There is a very simple (single-line) way of doing this, given that you get the employee results from the database first (so resultSetFromDatabase is just example data, you should have some LINQ query here that gets your results).
var a = new[] { "GUID1", "GUID2", "GUID3"};
var resultSetFromDatabase = new[]
{
new { IndividualProfileId = "GUID3", Name = "Joe Blo" },
new { IndividualProfileId = "GUID1", Name = "Maxy Dosh" },
new { IndividualProfileId = "GUID4", Name = "some one" },
new { IndividualProfileId = "GUID2", Name = "Max Walsh" }
};
var sortedResults = a.Join(res, s => s, e => e.IndividualProfileId, (s, e) => e);
It's impossible to have the datasource get the results directly in the right order, unless you're willing to write some dedicated SQL stored procedure. The problem is that you'd have to tell the database the contents of a. Using LINQ this can only be done via Contains. And that doesn't guarantee any order in the result set.
Turn the list(A), which you stated is a string, into an actual list. For example, you could use listAsString.Split(",") and then remove the 's from each element. I’ll assume the finished list is called list.
Query the database to retrieve the rows that you need, for example:
var data = db.Table.Where(row => list.Contains(row.IndividualProfileId));
From the data returned, create a dictionary keyed by the IndividualProfileId, for example:
var dic = data.ToDictionary(e => e.IndividualProfileId);
Iterate through the list and retrieve the dictionary entry for each item:
var results = list.Select(item => dic[item]).ToList();
Now results will have the records in the same order that the IDs were in list.

How do I save a transient object that already exists in an NHibernate session?

I have a Store that contains a list of Products:
var store = new Store();
store.Products.Add(new Product{ Id = 1, Name = "Apples" };
store.Products.Add(new Product{ Id = 2, Name = "Oranges" };
Database.Save(store);
Now, I want to edit one of the Products, but with a transient entity. This will be, for example, data from a web browser:
// this is what I get from the web browser, this product should
// edit the one that's already in the database that has the same Id
var product = new Product{ Id = 2, Name = "Mandarin Oranges" };
store.Products.Add(product);
Database.Save(store);
However, trying to do it this way gives me an error:
a different object with the same identifier value was already associated with the session
The reason is because the store.Products collection already contains an entity with the same Id. How do I get around this problem?
Instead of trying to merge the transient instance. Why not start with the actual instance...simply get the product by id, update the fields, and commit.
var product = session.Get<Product>(2);
product.Name = "Mandarin Oranges";
tx.Commit();
or the merge way...
var product = new Product{ Id = 2, Name = "Mandarin Oranges" };
var mergedProduct = (Product) session.Merge(product);
tx.Commit();
I'm not 100% positive in this case without more context, but a session merge might work.
http://ayende.com/Blog/archive/2009/11/08/nhibernate-ndash-cross-session-operations.aspx
Maybe You should call Database.SaveOrUpdate(store); instead of pure Save(store) ?

Categories