LLBLGen Audit Feature

Posts   
 
    
Posts: 18
Joined: 21-Mar-2011
# Posted on: 21-Mar-2011 14:51:54   

Hello,

there is llblgen generated code for database objects in our application. I am trying to use Audit feature to make back up files for all entities. I have made a DependencyInjection, which works good. I also need to mark which fields of entity has changed, so i am trying, for example:

private StringWriter ConstructAuditRecord(string affectedEntityName, AuditType actionType, string actionData, IEntityCore entity) { int fChanged=-1;

        IEntity2 ent = entity as IEntity2;

        if (ent != null)
        {
            fChanged = 0;
            for (int i = 0; i < ent.Fields.Count; i++)
                if (ent.Fields[i].IsChanged)
                    fChanged++;
        }

        StringWriter tmpAuditOfLoadEntitySW = new StringWriter();
        tmpAuditOfLoadEntitySW.WriteLine("{0} ---------------------------------------------------", DateTime.Now);
        tmpAuditOfLoadEntitySW.WriteLine("USER:   {0}", "testing");
        tmpAuditOfLoadEntitySW.WriteLine("ENTITY: {0}", affectedEntityName);
        tmpAuditOfLoadEntitySW.WriteLine("ACTION: {0}", actionType);
        tmpAuditOfLoadEntitySW.WriteLine("DATA:   {0}", actionData);
        tmpAuditOfLoadEntitySW.WriteLine("Number of changed fields:   {0}", fChanged.ToString());
        tmpAuditOfLoadEntitySW.WriteLine();

        return tmpAuditOfLoadEntitySW;
    }

where fChanged i would like to use for extra information. But when i am using this method from InsetOfNewEntity or update, for example, i can not access changed fields. I also tried to use method : public override void AuditEntityFieldSet(IEntityCore entity, int fieldIndex, object originalValue) { }

but it turned out to be not good for us, as our entity can update 5-6 tables per transaction and i would be better for us to access changed fields in methods like AuditUpdateOfExistingEntity, so then to take all changed fields at once.

Please, help me with that.

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 21-Mar-2011 15:19:20   

The AuditUpdateOfExistingEntity is called after the udate takes place. (hence it's an audit of an action that took place).

You can use AuditEntityFieldSet, to store the modifications in some member variable inside the Auditor, (Hashtable). Then you can use this member variable inside the AuditUpdateOfExistingEntity.

Posts: 18
Joined: 21-Mar-2011
# Posted on: 21-Mar-2011 16:06:25   

Thanks a lot for quick responce. I will try your suggestion. Thanks.

Posts: 18
Joined: 21-Mar-2011
# Posted on: 22-Mar-2011 12:28:22   

I tried your suggestion and find out, that method
public override void AuditEntityFieldSet(IEntityCore entity, int fieldIndex, object originalValue) {} works only with UserEntity in our project. It seems that setting values for other entities does fire that method.

Posts: 18
Joined: 21-Mar-2011
# Posted on: 22-Mar-2011 15:44:48   

Hello,

i decided to give you exta information about my issue. First, as i wrote earlier, i am using Dependency injection on my service. My auditor class look like:

[DependencyInjectionInfo(typeof(IEntity2), "AuditorToUse")] [Serializable] public class GeneralAuditor : AuditorBase { ......... }

When i am updating entity, i found that, for example, CfrcManufacturerEntity does not write log for method

/// <summary>CTor </summary> public GeneralAuditor() { _auditInfoEntities = new List<AuditInfoEntity>(); // clear temporal audit stream _auditInfoSW = new StringWriter(); _outputAuditFileName = "D:\Projects\CfrCoupons\Server\dev\Attachments\noraudit.txt";

    }

    /// <summary>
    /// Audits when an entity field is set succesfully to a new value.
    /// </summary>
    /// <param name="entity">The entity a field was set to a new value.</param>
    /// <param name="fieldIndex">Index of the field which got a new value.</param>
    /// <param name="originalValue">The original value of the field with the index passed in
    /// before it received a new value.</param>
    public override void AuditEntityFieldSet(IEntityCore entity, int fieldIndex, object originalValue)
    {
        StringWriter sw = new StringWriter();
        sw.WriteLine("AuditEntityFieldSet, entity - {0}", entity.GetType());
        AddAuditRecordStringToBulkStream(sw.ToString());
        // avoid to audit into AuditInfoEntity (this would create an overflow effect). This is necessary if this auditor is injected into
        // all entities, thus also in the AuditInfoEntity
        if (entity is AuditInfoEntity)
        {
            return;
        }



        if (((IEntity2)entity).Fields[fieldIndex].Name == "AppSettings")
            return;
        // used to store the change experimented by a field.
        string originalValueAsString = string.Empty;
        string currentValue = string.Empty;

        // sets VALUE OR NULL for originalValue and uses it as string.
        if (originalValue != null)
        {
            originalValueAsString = originalValue.ToString();
        }
        else
        {
            originalValueAsString = "NULL";
        }

        // sets VALUE OR NULL for currentValue and uses it as string.
        if (entity.GetCurrentFieldValue(fieldIndex) != null)
        {
            currentValue = entity.GetCurrentFieldValue(fieldIndex).ToString();
        }
        else
        {
            currentValue = "NULL";
        }

        // construct audit info record
        StringWriter auditInfo = ConstructAuditRecord(entity.LLBLGenProEntityName,
            AuditType.EntityFieldSet,
            string.Format("{0}. FieldSet: {1}. OriginalValue: {2}. CurrentValue: {3}",
                GetPrimaryKeyInfoFromEntity(entity),
                ((IEntity2)entity).Fields[fieldIndex].Name,
                originalValueAsString, currentValue), entity);

        // add to later-persist list
        AddAuditRecordStringToBulkStream(auditInfo.GetStringBuilder().ToString());
    }

This is my generated code for CfrcManufacturerEntity: <Snip>

I tried to look through all topics about common issue, read online documentation but i have not got to the point of my case. Please, help me with it.

MTrinder
User
Posts: 1461
Joined: 08-Oct-2008
# Posted on: 22-Mar-2011 17:35:29   

I edited your message as the generated code does not help us a whole lot. If I understand your issue correctly, your auditor works correctly in your User entity, but not in your CfrcManufacturerEntity, is that correct...?

If you run in debug mode, can you see if the auditor has been injected correctly into the CfrcManufacturerEntity entity ?

Matt

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 23-Mar-2011 06:14:31   

In addition to what Matt said: - Check if the auditor was really injected into AuditorToUse - The debugger should enter in the method where you set a field. Does this happen? - If the method is fine, but you just don't get the log info into your txt file, please attach your auditor file so we can check it.

David Elizondo | LLBLGen Support Team