您当前的位置: 首页 > 

寒冰屋

暂无认证

  • 4浏览

    0关注

    2286博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

查询审计历史

寒冰屋 发布时间:2021-03-10 21:09:01 ,浏览量:4

目录

选项

设想

怎么运行的

审核历史记录是模型驱动的应用程序中出色的即装即用功能。但是,查询审核历史记录有些棘手。不幸的是,诸如Power Automate CDS连接器,LinQ或简单的FetchXml之类的常用查询机制不支持它。这篇文章将讨论我们拥有的选项和示例代码。

选项
  1. 使用SDK消息RetrieveRecordChangeHistoryRequest和RetrieveRecordChangeHistoryResponse,本文中将对此进行介绍
  2. 使用Kingswaysoft的D365集成工具包(本文不涵盖)
设想

我将查询审计历史记录中的联系实体记录,并读取其电子邮件地址属性的审计详细信息。审计详细信息可从以下四个方面获得:

  • 变更日期
  • 变更栏位
  • 旧值
  • 新值

如果启用了审核,则此代码将适用于几乎所有实体和属性。

怎么运行的

我们需要实体的ID(GUID),并使用它们的ID来查询审核历史记录。我正在使用fetchxml查询来检索ID,但这可以是您选择的一种机制,具体取决于实现和要求。

var targetEntites_query = @"
                         
                          
                          ";

通常,我们知道FetchXml最多可以返回5000个实体,但是即使结果中有5000条以上的记录,该代码也会处理并返回。

public List RetrieveAllRecords(string fetch)
        {
            var moreRecords = false;
            int page = 1;
            var cookie = string.Empty;
            List Entities = new List();
            do
            {
                var xml = string.Format(fetch, cookie);
                var collection = CrmClient.RetrieveMultiple(new FetchExpression(xml));

                if (collection.Entities.Count >= 0) Entities.AddRange(collection.Entities);

                moreRecords = collection.MoreRecords;
                if (moreRecords)
                {
                    page++;
                    cookie = string.Format("paging-cookie='{0}' page='{1}'", 
                    System.Security.SecurityElement.Escape(collection.PagingCookie), page);
                }
            } while (moreRecords);

            return Entities;
        }

提示:FetchXml查询必须具有{0},如果返回5000条以上的记录。如果需要,可以在fetch中添加其他列。

接下来,我遍历这些ID并使用以下代码读取记录的审核历史记录:

public AuditDetailCollection GetAuditHistory(string entityLogicalName, Guid recordId)
       {
           var changeRequest = new RetrieveRecordChangeHistoryRequest();
           changeRequest.Target = new EntityReference(entityLogicalName, recordId);
           var changeResponse =
           (RetrieveRecordChangeHistoryResponse)this.CrmClient.Execute(changeRequest);
           return changeResponse.AuditDetailCollection;
       }

上面的函数返回AuditDetailCollection,其是一个AuditDetails集合。一个Audit细节代表审核历史记录中的一项。请注意,审核历史记录的顺序与它们在用户界面中出现的顺序相同(降序)。

每个审核详细信息记录的日期都会更改,并且将收集带有字段名称的新旧值,我们需要循环阅读这些值。

下面是实现此目的的代码:

         //Collection of entities for which we are going to read audit history
            var AllTargetEnteties = this.RetrieveAllRecords(targetEntites_query);

            foreach (var targetComplaint in AllTargetEnteties)
            {
                //Now pass id(guid) of record with entity name to retrieve audit history 
                var audit_history_entries = this.GetAuditHistory
                    (targetComplaint.LogicalName, targetComplaint.Id);

                foreach (AuditDetail auditDetail in audit_history_entries.AuditDetails)
                {
                    if ((auditDetail.GetType())?.Name == "AttributeAuditDetail")
                    {
                        //Below code reads Changed Date
                        var changeDate = 
                            auditDetail.AuditRecord.GetAttributeValue("createdon");

                        var newValueEntity = ((AttributeAuditDetail)auditDetail)?.NewValue;
                        if (newValueEntity.Attributes.Count > 0)
                        {
                            {
                                foreach (var attrNewValue in newValueEntity?.Attributes)
                                {
                                    //Here, we will need to 
                                    //match attribute name to read new value.
                                    //In this case, I'm reading emailaddress1
                                    if (attrNewValue.Key == "emailaddress1")
                                    {                                        
                                        var newEmailAddress = attrNewValue.Value;
                                        //Custom Logic for New Value here
                                    }
                                }
                            }
                        }

                        var oldValueEntity = ((AttributeAuditDetail)auditDetail)?.OldValue;
                        if (oldValueEntity.Attributes.Count > 0)
                        {
                            foreach (var attrOldValue in oldValueEntity?.Attributes)
                            {
                                //Here, we will need to match attribute name to read old value.
                                //In this case, I'm reading emailaddress1
                                if (attrOldValue.Key == "emailaddress1")
                                {
                                    var oldEmailAddress = attrOldValue.Value;
                                    //Custom logic for Old value will be here
                                }
                            }
                        }
                    }
                }
            }

希望对您有所帮助。

https://www.codeproject.com/Articles/5292977/Querying-Audit-History

关注
打赏
1665926880
查看更多评论
立即登录/注册

微信扫码登录

0.0587s