|
|
#1 |
|
Чайный пьяница
|
Создание и регистрация плагина на 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;
}
}Код: 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;
}
}Код: 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. |
|
|
|
|
#2 |
|
Moderator
|
Читать строку коннекции SQL из реестра, а так же делать прямые запросы - жесткий ансапорт! Перебирать XML... зачем такие сложности!!?? Используйте готовые сервисы!
__________________
http://fixrm.wordpress.com, снятие/наведение порчи. Быстро, дорого, гарантия. ![]() MS Certified Dirty Magic Professional
|
|
|
|
|
#3 |
|
Чайный пьяница
|
Цитата:
PS - для себя. О каких готовых сервисах идёт речь? Список ансапортеда - http://msdn.microsoft.com/en-us/library/bb928224.aspx и запросов к базе там ну нет. Структуру базы я не меняю. Последний раз редактировалось a33ik; 24.11.2008 в 15:18. |
|
|
|
|
#4 |
|
Участник
|
|
|
|
|
|
#5 |
|
Заноза в заднице
|
В целом, конечно право имеет, но есть вопросы:
1. "SOFTWARE\\Microsoft\\MSCRM" - разве не хард-код? Здесь намного правильнее было бы создать центральную консоль управления плагинами, в которой отдельными полями хранить данные о строке подключения и прочих разных параметрах. Данные об этом уместно складывать в веб-конфиг - он для того и предназначен. А лезть в реестр может только тот, у кого есть соответствующие права. У нас, например, правила безопасности таковы, что кто попало не имеет прав на читку реестра, даже если он админ в системе CRM. 2. Использование CrmService вызывает отторжение что-ли, я не пойму? С помощью CrmService можно выполнить все те же операции, приемлемыми для системы методами. К тому же, я полагаю, что скорость обработки будет гораздо быстрее.
__________________
Лень мудрого человека - это необходимое средство нейтрализации кипучей активности руководящих им дураков! |
|
|
|
|
#6 |
|
Moderator
|
Да незачем ее брать! Есть CrmService которым надо пользоваться! Помню помню, что для весьма специфичных задач он не подходит, но, как я уже говорил большинство из них преодолимо.
__________________
http://fixrm.wordpress.com, снятие/наведение порчи. Быстро, дорого, гарантия. ![]() MS Certified Dirty Magic Professional
|
|
|
|
|
#7 |
|
Чайный пьяница
|
Цитата:
Насчёт скорости - 100% быстрее будет работать прямой запрос, потому что звено короче на 1 - на веб сервис. Объясню, почему я ушёл от работы с веб сервисами. Механизм джоинов - конечно при работе с веб сервисами есть - через фетч и линкд ентити и прочее, но оно настолько громоздкое и нетривиальное, что для меня - как разработчика было проще написать прямой запрос к базе. |
|
|
|
|
#8 |
|
Moderator
|
С этим согласен - механизм построения запросов у Microsoft неимоверно убогий. Кто работал с Oracle TopLink меня поймет...
__________________
http://fixrm.wordpress.com, снятие/наведение порчи. Быстро, дорого, гарантия. ![]() MS Certified Dirty Magic Professional
|
|
|