Get ALL Entity Metadata in Dynamics CRM - dynamics-crm

What I want to do is:
Retrieve all metadata from CRM.
Serialize that metadata and store it in a file.
At a later point, deserialize and eed that metadata to XrmFakeEasy for unit tests.
Steps 2 and 3 are done but I don't know how to accomplish step 1.
I've spent some time noodling around in the code and on Google but remain stumped.
We're using .Net so what I need is to read ALL the Entity Metadata (type: Microsoft.Xrm.Sdk.Metadata.EntityMetadata).
If anyone knows how to do this or can point me in the direction of the API (I haven't been able to find one) then please let me know.
P.S.
This case is for on-premise crm.

If I get it right you need to use RetrieveAllEntitiesRequest request.
Here are more details: https://stackoverflow.com/a/29694213/2575544

For the benefit of anyone that comes across this post here's
My final solution
public static EntityMetadata[] GetMetadata(IOrganizationService crmService)
{
var request = new RetrieveAllEntitiesRequest
{
EntityFilters = EntityFilters.All
};
var response = (RetrieveAllEntitiesResponse) crmService.Execute(request);
return response.EntityMetadata;
}

Related

Is it possible to retrieve schema change information in Dynamics CRM online?

When a custom entity is created, a field is added or changed, someone makes an out-of-box changes to metadata.
How to know who did it and when?
The same for the creation or modification from a UI form. The metadata in CRM doesn't seem to store that information.
I think it is not possible to access information you're asking for. Such a information is not available in the on-premise CRM database and I suppose there is a similar situation with CRM Online
Not exactly what you are looking for. But this will be a good starting point to achieve what you want.
Using RetrieveMetadataChangesRequest, we can get the schema changes like:
Adding a custom entity named sample_SampleEntityForMetadataQuery with
a custom optionset attribute named : sample_ExampleOptionSet
ClientVersionStamp: 296646!10/22/2012 21:42:06
Adding an additional option to the sample_ExampleOptionSet attribute
options
Deleting the sample_SampleEntityForMetadataQuery custom entity
--
Sample code can be found in MSDN/SDK.
protected RetrieveMetadataChangesResponse getMetadataChanges(
EntityQueryExpression entityQueryExpression,
String clientVersionStamp,
DeletedMetadataFilters deletedMetadataFilter)
{
RetrieveMetadataChangesRequest retrieveMetadataChangesRequest = new RetrieveMetadataChangesRequest()
{
Query = entityQueryExpression,
ClientVersionStamp = clientVersionStamp,
DeletedMetadataFilters = deletedMetadataFilter
};
return (RetrieveMetadataChangesResponse)_service.Execute(retrieveMetadataChangesRequest);
}

Get all members from the mailing list using MailChimp API 3.0

http://kb.mailchimp.com/api/resources/lists/members/lists-members-collection
Using this resource we can obtain only first 10 members. How to get all?
The answer is quite simple - use offset and count parameters in URL query:
https://us10.api.mailchimp.com/3.0/lists/b5b5fdc2fa/members?offset=150&count=10
Finally I found PHP API client for MailChimp API v3:
https://github.com/pacely/mailchimp-api-v3
And official docs about pagination.. I missed it before :(
http://kb.mailchimp.com/api/article/api-3-overview
I stumbled on this one while researching a way to get all list members in MC API 3.0 as well. I noticed that there were some comments on the API timing out when trying to get all list members on one page. I also encountered this at first but was able to overcome it by limiting the fields in the result by using the 'fields' param. My code is for a mass deleter so all I really needed was the ID of each member to put together a batch delete request. Here's how my fetch request looks (psuedo-code):
$total_members = $result['total_items'];//get number of members in list via previous request
https://usXX.api.mailchimp.com/3.0/lists/foobarx/members?fields=members.id&count=total_members
This way I'm able to fetch over 15,000 subscribers on one page without error.
offset and count is the official way on the docs, but the problem is that has linear slowdown. It appears to be an n^2 solution, so if you have 20,000 items, you're in trouble. Their docs http://developer.mailchimp.com/documentation/mailchimp/reference/lists/members/#read-get_lists_list_id_members warn you against using offset.
If you're scenario permits you to use other filters (like since_last_changed), then you can do it quickly. See What is the right syntax for "timeframe" in MailChimp API 3.0 for format for datetime.
Using offset and count parameters are correct as mentioned in some of the other answers, but becomes tedious for large lists.
A more efficient way, is to use a client for the MailChimp API. I used mailchimp3 for python. Using this, it's pretty easy to get all members on your list because it handles the pagination. Here's how you would do it.
from mailchimp3 import MailChimp
client = MailChimp('YOUR_USERNAME', 'YOUR_SECRET_KEY')
client.lists.members.all('YOUR_LIST_ID', get_all=True, fields="members.email_address")
You can do it just with count, making an API call to the list root so in the next API call you include the count parameter and you have all your list members.
I ran into issues with this because I had a moderate list with 2600 members and MailChimp was throwing an error, but it worked with 1500 people.
So for a list bigger than 1500 members I use MailChimp export API bare in mind that this is going to get discontinued but I could not find any other acceptable solutions.
Alternatively for bigger lists (>1500) you could get the total of members and then make multiple api calls to the Member endpoint but I really dislike that :(
If anyone has a better alternative I would be really glad to hear it.
With MailChimp.Net.
Use the offset value.
List<Member> listMembers = new List<Member>();
IMailChimpManager manager = new MailChimpManager(MailChimpApiKey);
bool moreAvailable = true;
int offset = 0;
while (moreAvailable)
{
var listMembers = manager.Members.GetAllAsync(yourListId, new MemberRequest
{
Status = Status.Subscribed,
Limit = 250,
Offset = offset
}).ConfigureAwait(false);
var Allmembers = listMembers.GetAwaiter().GetResult();
foreach(Member member in Allmembers)
{
listMembers.Add(member);
}
if (Allmembers.Count() == 250)
//if the count is < of 250 then it means that there aren't more results
offset += 250;
else
moreAvailable = false;
}

How to retrieve data from SSAS Cube using EDMX?

I was given a cube with all relevant information. Now, I want to query cube and get the data through .net EDMX framework.
Could anyone help me out from where I should start on this? I am really confused and have no idea how to use MDX with edmx.
Is it possible to get the data from Cubes without using MDX using EDMX with LINQ?
It's not possible currently, there is a company who do a version of LinqToMdx, I think they've posted on here before, I don't think they go via the EDMX route exactly.
Standard method in .Net is ADOMD.Net http://msdn.microsoft.com/en-us/library/ms123477.aspx
A nice way of getting data is via the CellSet class, as it contains cells of both the native value and the formatted string for measures:
CellSet adomdCellSet;
using (var adomdConnection = new AdomdConnection())
{
adomdConnection.ConnectionString = "YourConnectionString";
adomdConnection.Open();
var adomdCommand = adomdConnection.CreateCommand();
adomdCommand.CommandText = "YourMDXQuery";
adomdCellSet = adomdCommand.ExecuteCellSet();
}
return adomdCellSet;
Edit: Found the site of the guys who wrote a provider - I can't vouch for them as I've never used it, but it looks interesting http://www.agiledesignllc.com/Products.htm

Getting new PurchId via .NET BusinessConnector

I am trying to find a .NET BusinessConnector equivalent call for the below line:
PurchId = NumberSeq::newGetNum(SalesParameters::numRefSalesId()).num();
I am manually entering purchase order information into the purchase order table, which is fine, but the problem lies in the fact that it is the PurchID that ties purchase table (PURCHTABLE) and the individual purchase order lines (PURCHLINE) is the PURCHID field, which is not automatically populated when saving a purchase order.
Currently I am:
ax.TTSBegin();
axRecord.set_Field("ORDERACCOUNT", purchaseOrder.OrderAccount);
(etc)
axRecord.Insert();
However, while this will insert a record into the database, it has no purchID, which has to be generated. You need a purchID to link the purchase line items in. I found the above code (second line) for X++, but does anyone know of a .NET BusinessConnector call that can be used instead?
Any assistance would be greatly appreciated.
Regards,
Steve
I would go for a change in the insert() method of the PurchTable table:
if (!purchTable.PurchId)
purchTable.PurchId = NumberSeq::newGetNum(purchParameters::numRefPurchId()).num();
Placed after the ttsbegin.
This to avoid complicated C# code. You probably could do it in C# code alone using CallStaticClassMethod and cousins, but it is better do put the buisness logic on the X++ side.
See How to: Call Business Logic Using .NET Business Connector.
Be sure to execute inside a TTSBegin/ TTSCommitblock, otherwise you will get error error messages like this one.
// ax is a reference to an "Axapta" business connector object
var numRef = ax.CallStaticRecordMethod("SalesParameters", "numRefSalesId");
var numSeq = (AxaptaObject)ax.CallStaticClassMethod("NumberSeq", "newGetNum", numRef);
var purchId = numSeq.Call("num");

Question - Should I use SPItemReceiver or SPEmailEventReceiver

I have custom SharePoint Document Library which I use to upload spreadsheet data into a database. When a spreadsheet is uploaded, the SPItemReceiver triggers, and upload the data.
Now, I would like to add an incoming email feature to the document library.
My question is...after the document library has received the spreadsheet by email. Should I use the override-able method EmailReceived of the SPEmailEventReceiver to process the data in the spreadsheet or still use the SPItemReceiver?
I gather I could use either, but I would like to know your opinion which is better and why.
Thanks in advance
You should use SPEmailEventReceiver to process the data. This will make it easy for you to maintain your code and debug. Below is the sample code to process the data. In this code itself, you can include the code to upload the data into database.
public class EmailHandler: SPEmailEventReceiver
{
public override void EmailReceived(
SPList objList,
SPEmailMessage objMessage,
string strReceiverData)
{
SPListItem objListItem = objList.Items.Add();
objListItem["Title"] = objMessage.Headers["Subject"];
objListItem["Body"] = objMessage.HtmlBody;
objListItem.Update();
}
}

Resources