Dynamics CRM 2011 中的自动编号
学习如何在 Dynamics CRM 2011 中为自定义实体创建自动编号系统。
引言
默认情况下,Dynamics CRM 2011 不提供在自定义实体上创建自动编号的功能;本文描述了我对此的解决方案。
对于此演示代码,我们将创建一个名为 TracknTrace (new_trackntrace) 的需要自动编号的应用程序。
必备组件
Dynamics CRM 2011 SDK。
为解决方案创建一个提供程序,我的命名为 XRM,前缀为 xrm。 如果您选择默认提供程序,则其前缀将为 new,并且所有实体都将以 new_ 开头,而不是我在此处使用的 xrm_。
创建实体
自动编号实体
首先,按照如下所示创建自动编号实体
然后创建用于保存计数器值的字段
此实体的最后一步是将计数器字段添加到表单
在自动编号实体中创建一个名为 CaseCounter 的新实体,计数器值为 0;这将保存插件的增量部分的值。
TrackNTrace 实体
创建 TrackNTrace 实体
创建两个字段;需要注意的是,xrm_SubTTNumber
是 TrackNTrace 实体上的查找,用于查找父 TrackNTrace 号码以创建子 TT。
最后,将这两个字段添加到 TrackNTrace 实体的表单中。 我已将 TrackNTrace 号码添加到表单的页眉中,因此没有人能够更改它,因为我们希望所有 TrackNTrace 号码都是系统生成的。
现在我们已经准备好实体,可以开始编码了。
代码
TrackNTrace 实体类
打开命令提示符并浏览到您的 crm2011sdk\bin 文件夹。
这将创建 TTEntities.cs 类,该类将保存来自您的 XRM 解决方案的实体,包括新添加的 xrm_AutoNumbering
和 xrm_TrackNTrace
。
插件的创建
打开 Visual Studio 并创建一个新的类项目。
从 SDKFolder\bin 文件夹中添加 Microsoft.crm.sdk.proxy.dll 和 microsoft.xrm.sdk.dkk。 从 .NET 列表中“添加引用”中添加 System.Runtime.Serialization
。 应该如下所示
将新生成的 TTEntities.cs 添加到项目。 默认情况下,它将位于 SDKFolder\bin 文件夹中。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
namespace AutoNumber
{
public class AutoNumber : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
var context = (IPluginExecutionContext)serviceProvider.GetService(
typeof(IPluginExecutionContext));
IOrganizationServiceFactory factory =
(IOrganizationServiceFactory)serviceProvider.GetService(
typeof(IOrganizationServiceFactory));
ITracingService tracingService =
(ITracingService)serviceProvider.GetService(typeof(ITracingService));
if (context.InputParameters.Contains("Target") &&
context.InputParameters["Target"] is Entity)
{
// Obtain the target entity from the input parmameters.
Entity entity = (Entity)context.InputParameters["Target"];
//Verify that the target entity represents an account.
// If not, this plug-in was not registered correctly.
if (entity.LogicalName == "xrm_trackntrace")
{
// An accountnumber attribute should not already exist because
// it is system generated.
if (entity.Attributes.Contains("xrm_ttnumber") == false)
{
IOrganizationService service =
factory.CreateOrganizationService(context.UserId);
OrganizationServiceContext orgContext =
new OrganizationServiceContext(service);
if (entity.Attributes.Contains("xrm_subttnumber") == true)
{
var ttGuid = ((EntityReference)entity["xrm_subttnumber"]).Id;
//Grab case to create subcase on
var subTT = (from CN in orgContext.CreateQuery<xrm_trackntrace>()
where CN.Id == ttGuid
select CN).First();
//Check for existing sub TT numbers
var checkForCounter =
from entry in orgContext.CreateQuery<xrm_autonumbering>()
where entry.xrm_name == subTT.xrm_TTNumber
select entry;
int i = 0;
foreach (var t in checkForCounter)
{
i++;
}
//if sub tt doesnt exist, create counter for sub tt
if (i == 0)
{
var counter = new xrm_autonumbering()
{
xrm_name = subTT.xrm_TTNumber,
xrm_Counter = 0
};
orgContext.AddObject(counter);
orgContext.SaveChanges();
}
// read from sub tt and tt number and set
// this number as TTNUBMER - SUBTTNUMBER on the form. Save changes
var subCounter = checkForCounter.First();
var sub = subCounter.xrm_Counter + 1;
var main = subTT.xrm_TTNumber;
entity.Attributes.Add("xrm_ttnumber", main + "-" + sub.ToString());
subCounter.xrm_Counter = sub;
orgContext.UpdateObject(subCounter);
orgContext.SaveChanges();
}
else
{
//if no sub tt has been selected create new, grab counter
//from CaseCounter entry and add 1, save after this
var query = from CN in orgContext.CreateQuery<xrm_autonumbering>()
where CN.xrm_name == "CaseCounter"
select CN;
foreach (var entry in query)
{
var t = entry.xrm_Counter + 1;
entity.Attributes.Add("xrm_ttnumber", t.ToString());
entry.xrm_Counter = t;
orgContext.UpdateObject(entry);
orgContext.SaveChanges();
}
}
}
}
else
{
throw new InvalidPluginExecutionException(
"TrackNTrace Number can only be set by the system.");
}
}
}
}
}
源代码和 CRM 2011 解决方案在 Zip 文件中。
免责声明
代码可能不是有史以来最美观和最美观的,但它有效,并且会让你了解如何完成这项任务。
历史
- 2011 年 5 月 11 日 - 初始发布。
- 2011 年 5 月 22 日 - 较小的拼写错误更新。