Показать сообщение отдельно
Старый 24.11.2008, 11:07   #1  
a33ik is offline
a33ik
Чайный пьяница
Аватар для a33ik
MCP
MCBMSS
Злыдни
Соотечественники
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,243 / 896 (36) +++++++
Регистрация: 02.07.2008
Адрес: Greenville, SC
Создание и регистрация плагина на Execute и Retreive
Задача, которая была поставлена - необходимо было в целочисленные поля new_hour и new_min сущности new_task - возвращать часы и минуты в работе с задачей соответственно. Механику вычисления - пропущу, потому как она для каждого отдельного случая может быть уникальна.

1. Особенности регистрации - плагин на Execute (в моём случае я отслеживал получение данных в гриды MS CRM) необходимо регистрировать на Post Event не выбирая сущность и поля. Плагин на Retreive - необходимо регистрировать на Post Event, указывая имя сущности.

2. Особенности реализации:

Execute:

Код:
public override void Execute(IPluginExecutionContext context)
{
       //метод для получения строки подключения к базе MS CRM будет приведён ниже
        string sqlConnectionString = GetSqlConnectionString(context.OrganizationName);

	//контролируем, что было событие Execute и Возвоащается FetchXml
	if (context.MessageName == "Execute" && context.InputParameters.Contains("FetchXml"))
	{
		XmlDocument indoc = new XmlDocument();
		indoc.LoadXml((string)context.InputParameters["FetchXml"]);

		//контролируем имя сущности поиск по которой был выполнен
		entityName = indoc.SelectSingleNode("//fetch/entity").Attributes["name"].InnerText;
				
		if (entityName != "new_task")
			return;
				
		//получаем Xml, который возвращается на сторону клиента
		XmlDocument outdoc = new XmlDocument();
				outdoc.LoadXml((string)context.OutputParameters["FetchXmlResult"]);

		foreach (XmlNode node in outdoc.SelectNodes("//resultset/result"))
		{
			Guid recordId = new Guid(node.SelectSingleNode("./new_taskid").InnerText);

			//чтобы не путать читателя кода поясню - GetWorkingMinutesCount - метод, который зачитывает данные из MS SQL сервера
			//в данном случае - время выполнения задачи в минутах
			calcMinCount = GetWorkingMinutesCount(recordId, sqlConnectionString);					
				
			XmlNode hoursnode = node.SelectSingleNode("./new_hour");
			if (hoursnode != null)
			{
				hoursnode.Attributes["formattedvalue"].Value =
				hoursnode.InnerText = ((int)(calcMinCount / 60)).ToString();
			}

			XmlNode minsnode = node.SelectSingleNode("./new_mins");
			if (minsnode != null)
			{
				minsnode.Attributes["formattedvalue"].Value =
				minsnode.InnerText = ((int)(calcMinCount % 60)).ToString();
			}
		}

		//возвращаем на клиента уже отформатированный Xml
		context.OutputParameters["FetchXmlResult"] = outdoc.OuterXml;
	}
}
Retreive:

Код:
public override void Execute(IPluginExecutionContext context)
{
	if (context.MessageName == "Retrieve")
	{
		entityName = context.PrimaryEntityName;

		//контролирую имя сущности, получение которой ведётся при помощи Retreive - например при открытии карточки
		if (entityName != "new_task")
			return;


		DynamicEntity currentEntity = (Microsoft.Crm.Sdk.DynamicEntity)context.OutputParameters.Properties["BusinessEntity"];
		if (!currentEntity.Properties.Contains("new_hour") && !currentEntity.Properties.Contains("new_mins"))
			return;

		Guid recordId = ((Microsoft.Crm.Sdk.Key)currentEntity.Properties["new_taskid"]).Value;


		string sqlConnectionString = GetSqlConnectionString(context.OrganizationName);
		int calcMinCount = GetWorkingMinutesCount(recordId, sqlConnectionString);

		if (currentEntity.Properties.Contains("new_hour"))
			((CrmNumber)currentEntity.Properties["new_hour"]).Value = calcMinCount / 60;

		if (currentEntity.Properties.Contains("new_mins"))
			((CrmNumber)currentEntity.Properties["new_mins"]).Value = calcMinCount % 60;
	}

}
Метод для получения строки подключения к базе MS CRM без хардкода:

Код:
		protected string GetSqlConnectionString(string orgname)
		{
			RegistryKey key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\MSCRM");

			//Retreive MSCRM DataBase connection string
			string configDBConnectionString = key.GetValue("configdb").ToString();

			//next part - i connect to config db and retreive data to config connection to client db
			DataSet clientDBConnectionData = new DataSet();

			using (SqlConnection connection = new SqlConnection(configDBConnectionString))
			{
				connection.Open();

				using (SqlCommand cmd = new SqlCommand())
				{
					cmd.Connection = connection;
					cmd.CommandType = CommandType.Text;
					cmd.CommandText = string.Format("Select SqlServerName, DatabaseName From Organization Where UniqueName = '{0}'", orgname);

					using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
						adapter.Fill(clientDBConnectionData);
				}

				connection.Close();
			}

			if (clientDBConnectionData.Tables.Count == 0 || clientDBConnectionData.Tables[0].Rows.Count == 0)
				throw new Exception("Check your config parameters!");

			string connectionString = string.Format("Data Source={0};Initial Catalog={1};Integrated Security=SSPI",
					new object[] { (string)clientDBConnectionData.Tables[0].Rows[0]["SqlServerName"], 
											   (string)clientDBConnectionData.Tables[0].Rows[0]["DatabaseName"]});

			return connectionString;
		}

Последний раз редактировалось a33ik; 24.11.2008 в 11:20.