Dataverse開発：XRM TOOLの使い方

サンプルソースコードは、.net framework 4.7使用

# App.config接続情報を設定
```
<connectionStrings>
	<add name="connect" connectionString="AuthType=OAuth;Username=メールアドレス;Password=パスワード;Url=https://テナント.api.crm.dynamics.com/;AppId=クライアンちID;RedirectUri=https://localhost/;LoginPrompt=Auto" />
</connectionStrings>
```
# Dataverse 接続＆CRUD
```
using System;
using System.Configuration;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Tooling.Connector;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading.Tasks;

//データベース接続とデータINSERTなど
public class ConnectDataverse
{

    /// <summary>
    /// Gets a named connection string from App.config
    /// </summary>
    /// <param name="name">The name of the connection string to return</param>
    /// <returns>The named connection string</returns>
    private static string GetConnectionStringFromAppConfig(string name)
    {
        //Verify cds/App.config contains a valid connection string with the name.
        try
        {
            return ConfigurationManager.ConnectionStrings[name].ConnectionString;
        }
        catch (Exception)
        {
            Console.WriteLine("You can set connection data in cds/App.config before running this sample. - Switching to Interactive Mode");
            return string.Empty;
        }
    }
    //接続
    public static CrmServiceClient Connect(string name)
    {
        CrmServiceClient service = null;

        //You can specify connection information in cds/App.config to run this sample without the login dialog
        if (string.IsNullOrEmpty(GetConnectionStringFromAppConfig("Connect")))
        {


        }
        else
        {
            // Try to create via connection string. 
            service = new CrmServiceClient(GetConnectionStringFromAppConfig("Connect"));

        }

        return service;

    }


    /// <summary>
    /// Function to set up the Client.
    /// </summary>
    /// <param name="service">Specifies the service to connect to.</param>
    public static void SetUpClient(CrmServiceClient service)
    {

    }
    /// <summary>
    /// Method to clean up any Client data
    /// </summary>
    /// <param name="service">Specifies the service to connect to.</param>
    public static void CleanUpClient(CrmServiceClient service)
    {

    }
     //大量のデータをinsertする時、parallelを使うと、処理速度が爆速
    /// <summary>
    /// Creates entities in parallel
    /// </summary>
    /// <param name="svc">The CrmServiceClient instance to use</param>
    /// <param name="entities">A List of entities to create.</param>
    /// <returns></returns>
    public static ConcurrentBag<EntityReference> CreateEntities(CrmServiceClient svc, List<Entity> entities)
    {
        var createdEntityReferences = new ConcurrentBag<EntityReference>();

        Parallel.ForEach(entities,
            new ParallelOptions() { MaxDegreeOfParallelism = svc.RecommendedDegreesOfParallelism },
            () =>
            {
                //Clone the CrmServiceClient for each thread
                return svc.Clone();
            },
            (entity, loopState, index, threadLocalSvc) =>
            {
                // In each thread, create entities and add them to the ConcurrentBag
                // as EntityReferences
                createdEntityReferences.Add(
                    new EntityReference(
                        entity.LogicalName,
                        threadLocalSvc.Create(entity)
                        )
                    );

                return threadLocalSvc;
            },
            (threadLocalSvc) =>
            {
                //Dispose the cloned CrmServiceClient instance
                if (threadLocalSvc != null)
                {
                    threadLocalSvc.Dispose();
                }
            });

        //Return the ConcurrentBag of EntityReferences
        return createdEntityReferences;
    }
}
```

# Datavere初期化

```
using Microsoft.Xrm.Tooling.Connector;

class Program
{

        [STAThread] // Added to support UX
        static async Task Main(string[] args)
        {
            logger.Info(Const.MGI0001);
            #region Optimize Connection settings

            //Change max connections from .NET to a remote service default: 2
            System.Net.ServicePointManager.DefaultConnectionLimit = 65000;
            //Bump up the min threads reserved for this app to ramp connections faster - minWorkerThreads defaults to 4, minIOCP defaults to 4
            System.Threading.ThreadPool.SetMinThreads(100, 100);
            //Turn off the Expect 100 to continue message - 'true' will cause the caller to wait until it round-trip confirms a connection to the server
            System.Net.ServicePointManager.Expect100Continue = false;
            //Can decreas overall transmission overhead but can cause delay in data packet arrival
            System.Net.ServicePointManager.UseNagleAlgorithm = false;

            #endregion Optimize Connection settings

            CrmServiceClient service = null;
            try
            {

                service = DataverseApi.Connect("Connect");
                if (service != null && service.IsReady)
                {
                    logger.Info("Dataverseは接続が成功しました。");

                    // Generate a list of account entities to create.
                    var accountsToImport = new List<Entity>();
                    var count = 0;
                    while (count < numberOfRecords)
                    {
                        var account = new Entity("account");
                        account["name"] = $"Account {count}";
                        accountsToImport.Add(account);
                        count++;
                    }

                   
                    //Import the list of accounts
                    var createdAccounts = CreateEntities(service, accountsToImport);
                    
                }
                else
                {
                    const string UNABLE_TO_LOGIN_ERROR = "Unable to Login to Dynamics CRM";
                    if (service.LastCrmError.Equals(UNABLE_TO_LOGIN_ERROR))
                    {
                        logger.Error(service.LastCrmError);
                        throw new Exception(service.LastCrmError);
                    }
                    else
                    {
                        logger.Error(service.LastCrmError);
                        throw service.LastCrmException;
                    }
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
            finally
            {
                if (service != null)
                    service.Dispose();
                logger.Info("Dataverseは接続が終了しました。");
                Console.WriteLine("Press any key to exit");
                Console.ReadKey();
            }
        }       
}
```

 # 参考サイト
https://learn.microsoft.com/ja-jp/power-apps/developer/data-platform/xrm-tooling/use-xrm-tooling-create-data

https://learn.microsoft.com/en-us/power-apps/developer/data-platform/xrm-tooling/sample-tpl-crmserviceclient