Задача, которая была поставлена - необходимо было в целочисленные поля 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;
}