Loading ...

Acumatica DAC class generator

Hello everyboydy,

today I want to share with anybody mine implementation of DAC class generator.

By default Acumatica provides you with DAC class generator which is pretty good.

But time from the time I had a need to generate DAC class into text field, and then

put it somewhere in my solution, and Acumatica DAC class generator didn't feet to

mine needs. So I decided to create my own DAC class generator. 

 

This form has simple interface. In the first line you enter Connection string, at second




line you enter table name, press at generate, and receive DAC class.

 

Acumaitca_DAC_Generator-1.png

 

Below goes also some C# code which I've comment later:

    public static string FirstCharToUpper(string input)
    {
        if (String.IsNullOrEmpty(input))
            throw new ArgumentException("ARGH!");
        return input.First().ToString().ToUpper() + String.Join("", input.Skip(1));
    }
 
    public static string FirstCharToLower(string input)
    {
        if (String.IsNullOrEmpty(input))
            throw new ArgumentException("ARGH!");
        return input.First().ToString().ToLower() + String.Join("", input.Skip(1));
    }
 
    private void btnGenerate_Click(object sender, EventArgs e)
    {
        string cSharp = "[Serializable]\r\n";
        cSharp += $"public class {txtTableName.Text} : IBqlTable \r\n        {{";
 
        var columnNames = GetColumnsNames(txtTableName.Text);
 
        foreach (var column in columnNames)
        {
            string abstractClassName = FirstCharToLower(column.ColumnName);
            string memberFieldName = FirstCharToUpper(column.ColumnName);
            string propertyName = "_" + memberFieldName;
            string caption = SplitCamelCase(memberFieldName);
 
            if (column.ColumnType == "int")
            {
                string intImplementation =
                    $"\r\n        #region {memberFieldName}\r\n        public abstract class {abstractClassName} : IBqlField\r\n        {{\r\n        }}\r\n\r\n        " +
                    $"[PXDBInt()]\r\n        [PXUIField(DisplayName = \"{caption}\", " +
                    $"Visibility = PXUIVisibility.Visible, Visible = false, Enabled = false)]\r\n        " +
                    $"public virtual int? {memberFieldName} {{ get; set; }}\r\n\r\n        #endregion\r\n";
                cSharp += intImplementation;
            }
            if (column.ColumnType == "nvarchar")
            {
                int length = column.MaximumLength.Value;
                string nvarcharImplementation =
                    $"\r\n         #region route\r\n        public abstract class {abstractClassName} : IBqlField\r\n        " +
                    $"{{\r\n        }}\r\n        [PXDBString({length})]\r\n        [PXUIField(DisplayName = \"{caption}\", Visibility = PXUIVisibility.Visible)]\r\n        " +
                    $"public virtual string {memberFieldName} {{ get; set; }}\r\n        #endregion\r\n";
                cSharp += nvarcharImplementation;
            }
            if (column.ColumnType == "decimal")
            {
                int length = column.NumericScalse.Value;
                string decimalImplementation =
                    $"\r\n        #region {memberFieldName}\r\n        public abstract class {abstractClassName} : IBqlField\r\n      " +
                    $"  {{\r\n        }}\r\n        [PXDBDecimal({length})]\r\n        [PXDefault(TypeCode.Decimal, \"0.0\")] \r\n        " +
                    $"[PXUIField(DisplayName = \"{caption}\", Visibility = PXUIVisibility.Visible)]\r\n      " +
                    $"  public virtual decimal? {memberFieldName} {{ get; set; }}\r\n        #endregion\r\n";
                cSharp += decimalImplementation;
            }
            if (column.ColumnType =="datetime")
            {
                string datetimeImplementation =
                    $"\r\n        #region {memberFieldName}\r\n        public abstract class {abstractClassName}  : IBqlField\r\n        " +
                    $"{{\r\n        }}\r\n        [PXDBDate()]\r\n        [PXUIField(DisplayName = \"{caption}\", " +
                    $"Visibility = PXUIVisibility.SelectorVisible)]\r\n        " +
                    $"public virtual DateTime? {memberFieldName} {{ get; set; }}\r\n        #endregion\r\n";
                cSharp += datetimeImplementation;
            }
        }
 
        string serviceFields =
            "        #region CreatedByID\r\n\t\tpublic abstract class createdByID : IBqlField\r\n\t\t{\r\n\t\t}\r\n\t\tprotected Guid? " +
            "_CreatedByID;\r\n\t\t[PXDBCreatedByID()]\r\n\t\tpublic virtual Guid? CreatedByID\r\n\t\t{\r\n\t\t\tget\r\n\t\t\t{\r\n\t\t\t\treturn " +
            "this._CreatedByID;\r\n\t\t\t}\r\n\t\t\tset\r\n\t\t\t{\r\n\t\t\t\tthis._CreatedByID = value;\r\n\t\t\t}\r\n\t\t}\r\n\t\t#endregion\r\n\t\t#region " +
            "CreatedByScreenID\r\n\t\tpublic abstract class createdByScreenID : " +
            "PX.Data." +
            "IBqlField\r\n\t\t{\r\n\t\t}\r\n\t\tprotected String _CreatedByScreenID;\r\n\t\t[PXDBCreatedByScreenID()]\r\n\t\tpublic virtual " +
            "String CreatedByScreenID\r\n\t\t{\r\n\t\t\tget\r\n\t\t\t{\r\n\t\t\t\treturn " +
            "this._CreatedByScreenID;\r\n\t\t\t}\r\n\t\t\tset\r\n\t\t\t{\r\n\t\t\t\tthis._CreatedByScreenID = value;\r\n\t\t\t}\r\n\t\t}\r\n\t\t" +
            "#endregion\r\n\t\t#region CreatedDateTime\r\n\t\tpublic abstract class createdDateTime : IBqlField\r\n\t\t{\r\n\t\t}\r\n\t\tprotected DateTime? " +
            "_CreatedDateTime;\r\n\t\t[PXDBCreatedDateTime()]\r\n\t\tpublic virtual DateTime? " +
            "CreatedDateTime\r\n\t\t{\r\n\t\t\tget\r\n\t\t\t{\r\n\t\t\t\treturn this._CreatedDateTime;\r\n\t\t\t}\r\n\t\t\tset\r\n\t\t\t{\r\n\t\t\t\tt" +
            "his._CreatedDateTime = value;\r\n\t\t\t}\r\n\t\t}\r\n\t\t#endregion\r\n\t\t#region LastModifiedByID\r\n\t\tpublic " +
            "abstract class lastModifiedByID : IBqlField\r\n\t\t{\r\n\t\t}\r\n\t\tprotected Guid? " +
            "_LastModifiedByID;\r\n\t\t[PXDBLastModifiedByID()]\r\n\t\tpublic virtual Guid? LastModifiedByID\r\n\t\t{\r\n\t\t\t" +
            "get\r\n\t\t\t{\r\n\t\t\t\treturn this._LastModifiedByID;\r\n\t\t\t}\r\n\t\t\tset\r\n\t\t\t{\r\n\t\t\t\t" +
            "this._LastModifiedByID = value;\r\n\t\t\t}\r\n\t\t}\r\n\t\t#endregion\r\n\t\t#region LastModifiedByScreenID\r\n\t\tpublic abstract class " +
            "lastModifiedByScreenID : PX.Data.IBqlField\r\n\t\t{\r\n\t\t}\r\n\t\tprotected String _LastModifiedByScreenID;\r\n\t\t" +
            "[PXDBLastModifiedByScreenID()]\r\n\t\tpublic virtual String LastModifiedByScreenID\r\n\t\t{\r\n\t\t\tget\r\n\t\t\t{\r\n\t\t\t\t" +
            "return this._LastModifiedByScreenID;\r\n\t\t\t}\r\n\t\t\tset\r\n\t\t\t{\r\n\t\t\t\tthis._LastModifiedByScreenID = " +
            "value;\r\n\t\t\t}\r\n\t\t}\r\n\t\t#endregion\r\n\t\t#region LastModifiedDateTime\r\n\t\tpublic abstract class lastModifiedDateTime : " +
            "IBqlField\r\n\t\t{\r\n\t\t}\r\n\t\tprotected DateTime? _LastModifiedDateTime;\r\n\t\t[PXDBLastModifiedDateTime()]\r\n\t\tpublic virtual DateTime? " +
            "LastModifiedDateTime\r\n\t\t{\r\n\t\t\tget\r\n\t\t\t{\r\n\t\t\t\treturn " +
            "this._LastModifiedDateTime;\r\n\t\t\t}\r\n\t\t\tset\r\n\t\t\t{\r\n\t\t\t\tthis._LastModifiedDateTime = value;" +
            "\r\n\t\t\t}\r\n\t\t}\r\n\t\t#endregion\r\n\t\t#region tstamp\r\n\t\tpublic abstract class Tstamp : " +
            "PX.Data.IBqlField" +
            "\r\n\t\t{\r\n\t\t}\r\n\t\tprotected Byte[] _tstamp;\r\n\t\t[PXDBTimestamp]\r\n\t\tpublic virtual Byte[] " +
            "tstamp\r\n\t\t{\r\n\t\t\tget\r\n\t\t\t{\r\n\t\t\t\treturn this._tstamp;\r\n\t\t\t}\r\n\t\t\tset\r\n\t\t\t{\r\n\t\t\t\tthis._tstamp = value;" +
            "\r\n\t\t\t}\r\n\t\t}\r\n\t\t#endregion";
        cSharp += serviceFields;
        cSharp += "\t\t\r\n}\r\n}";
        txtDacClass.Text = cSharp;
    }
 
    public string SplitCamelCase(string inputString)
    {
        return Regex.Replace(inputString, "(?<=[a-z])([A-Z])"" $1"RegexOptions.Compiled);
    }
 
    public List<ColumnForDacInfo> GetColumnsNames(string tableName)
    {
        List<ColumnForDacInfo> result = new List<ColumnForDacInfo>();
        using (SqlConnection connection = new SqlConnection(txtConnectionString.Text))
        using (SqlCommand command = connection.CreateCommand())
        {
            command.CommandText = $"select * from information_schema.columns where table_name = '{tableName}'";
            connection.Open();
            using (var reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    var col = new ColumnForDacInfo();
                    col.ColumnName = reader.GetString(
                        reader.GetOrdinal("COLUMN_NAME")
                        );
                    col.ColumnType = reader.GetString(reader.GetOrdinal("DATA_TYPE"));
                    col.ColumnName = reader.GetString(reader.GetOrdinal("COLUMN_NAME"));
                    try
                    {
                        col.MaximumLength = reader.GetInt32(reader.GetOrdinal("CHARACTER_MAXIMUM_LENGTH"));
                    }
                    catch (Exception)
                    {
                    }
 
                    try
                    {
                        col.NumericPresicion = reader.GetInt32(reader.GetOrdinal("NUMERIC_PRECISION"));
                    }
                    catch (Exception)
                    {
                    }
                    try
                    {
                        col.NumericScalse = reader.GetInt32(reader.GetOrdinal("NUMERIC_SCALE"));
                    }
                    catch (Exception)
                    {
                    }
                    try
                    {
                        col.IsNullable = reader.GetString(reader.GetOrdinal("IS_NULLABLE"));
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e);
                    }
 
                    if (!ExcludeFromGeneration.Contains(col.ColumnName))
                    {
                        result.Add(col);
                    }
                }
            }
        }
        return result;
    }
 
    public List<string> ExcludeFromGeneration
    {
        get
        {
            var excludeFromGeneration = new List<string>();
            excludeFromGeneration.Add("CompanyID");
            excludeFromGeneration.Add("tstamp");
            excludeFromGeneration.Add("CreatedByID");
            excludeFromGeneration.Add("CreatedByScreenID");
            excludeFromGeneration.Add("CreatedDateTime");
            excludeFromGeneration.Add("LastModifiedByID");
            excludeFromGeneration.Add("LastModifiedByScreenID");
            excludeFromGeneration.Add("LastModifiedDateTime");
            return excludeFromGeneration;
        }
    }
}

Method FirstCharToUpper as input takes string and returns capitalized first character.

Method SplitCamelCase takes string like "stringLikeThis" and will make it like "string Like This".

Method GetColumNames reads needed information about columns. 

And of course meat of code is btnGenerate_Click method which creates string which you can than copy/paste in your solution.