1

I have added a new control to my .NET form and I want to save its value in a table.I have added a new column in my table.How do you use MyGeneration Doodads to create a data access object for this table?I have looked at http://www.mygenerationsoftware.com/portal/doodads/cusage/tabid/53/default.aspx but I can't understand what it means by "template".What is the procedure to regenerate doodads for a table?

user2350631
  • 61
  • 1
  • 5

2 Answers2

3

You wont get much of a response on this... dOOdads have not been supported for many years. Regardless, we use dOOdads too and I just roll my own repositories for my WPF projects (I know it's not ASP, but I don't think you can just "plug-and-play"). Here is an example of my base lookup class:

public abstract class BaseLookup<TEntity>
{
    // Constructor

    protected BaseLookup()
    {
        this.SubsetIdentifier = null;
    }

    // Properties

    public virtual object SubsetIdentifier { get; set; }

    // Public Methods

    public abstract IEnumerable<TEntity> Read();

    public virtual TEntity ReadSingle()
    {
        return default(TEntity);
    }

    // Protected Methods

    /// <summary>
    /// Retrieve translated entities from the database. The methods used to do this
    /// are specified from the child class as parameters (i.e. Action or Func delegates).
    /// </summary>
    /// <param name="loadSubsetFunc">Specify how to load a set of database records.
    /// Return boolean confirmation that records were found.</param>
    /// <param name="orderByAction">Specify what should happen to sort the results.</param>
    /// <param name="translateRowFunc">Specify how a database record should translate to
    /// a model entity. Return the new entity.</param>
    /// <param name="moveNextFunc">Specify how the database row pointer should move on.
    /// Return FALSE on a call to the final row.</param>
    /// <returns>A set of translated entities from the database.</returns>
    /// <example><code>
    ///
    /// return base.ReloadRecords(
    ///     _dOOdad.LoadAll,
    ///     () =>
    ///     {
    ///         _dOOdad.Sort = _dOOdad.GetAutoKeyColumn();
    ///     },
    ///     () =>
    ///     {
    ///         var entity = new LookupEntity();
    ///         return entity.PopulateLookupEntity(_dOOdad.CurrentRow.ItemArray);
    ///     },
    ///     _dOOdad.MoveNext);
    ///     
    /// </code></example>
    protected virtual IEnumerable<TEntity> ReloadRecords(Func<bool> loadSubsetFunc,
        Action orderByAction, Func<TEntity> translateRowFunc, Func<bool> moveNextFunc)
    {
        // If records are found, sort them and return set of entities
        if (loadSubsetFunc())
        {
            orderByAction();

            do
            {
                var entity = translateRowFunc();
                yield return entity;
            }
            while (moveNextFunc());
        }
        else
        {
            Debug.WriteLine(
                string.Format(
                    "# ZERO records found: Returning empty set of {0}.",
                    typeof(TEntity).Name));
        }
    }
}

And here is a concrete implementation of the base lookup:

public class CyclesLookup : BaseLookup<BaseLookupEntity>
{
    // Fields & Constructor

    private readonly CYCLES _dOOdad;

    public CyclesLookup(IDbConnection connection, string library)
    {
        _dOOdad = OpenConnection(connection, library);
    }

    // Base Override Methods

    public override IEnumerable<BaseLookupEntity> Read()
    {
        // Clear old result set and settings
        _dOOdad.FlushData();

        // Reload the records and return them sorted and translated
        return base.ReloadRecords(
            _dOOdad.LoadAll,
            () =>
            {
                _dOOdad.Sort = _dOOdad.GetAutoKeyColumn();
            },
            () =>
            {
                var entity = new LookupEntity();
                entity.Description = string.Format("Cycles for {0}", _dOOdad.YEAR);
                return entity.PopulateLookupEntity(_dOOdad.CurrentRow.ItemArray, true);
            },
            _dOOdad.MoveNext);
    }

    // Private Helper Methods

    private static CYCLES OpenConnection(IDbConnection connection, string library)
    {
        var dOOdad = new CYCLES(connection);
        dOOdad.SchemaGlobal = library + ".";
        return dOOdad;
    }
}

That PopulateLookupEntity method is just an extension method:

public static T PopulateLookupEntity<T>(this T entity, object[] rowItems,
    bool noDescription = false) where T : BaseLookupEntity
{
    int id = 0;
    int.TryParse(rowItems[0].ToString(), out id);
    entity.RecordID = id;

    var attributesFirstIndex = 1;
    if (!noDescription)
    {
        entity.Description = rowItems[1].ToString();
        attributesFirstIndex = 2;
    }

    entity.Attributes = new object[rowItems.Length - attributesFirstIndex];
    for (int index = attributesFirstIndex; index < rowItems.Length; index++)
    {
        entity.Attributes[index - attributesFirstIndex] = rowItems[index];
    }

    return (T)entity;
}

For non-lookups, I have a more complex BaseRepository class that inherits from BaseLookup. With that one, I don't use PopulateLookupEntity, but a private helper method like this:

private IPlanningGridHeader TranslateCurrentDoodadRow()
{
    return new PlanningGridHeader()
    {
        PlanNumber = Convert.ToInt32(_dOOdad.PLANNUMBER),
        Active = _dOOdad.ACTIVE == 1M,
        Capturer = _dOOdad.CAPTURER,
        Region = _dOOdad.REGION,
        CorporateID = Convert.ToInt32(_dOOdad.CORPORATEID),
        StartDate = _dOOdad.STARTDATE.ConvertDb2Date(),
        EndDate = _dOOdad.ENDDATE.ConvertDb2Date(),
        AdvertStartDate = _dOOdad.ADVERTSTARTDATE.ConvertDb2Date(),
        AdvertEndDate = _dOOdad.ADVERTENDDATE.ConvertDb2Date(),
        BpcsDealNumber = Convert.ToInt32(_dOOdad.BPCSDEALNUMBER),
        Description = _dOOdad.DESCRIPTION,
        DeactivationReason = _dOOdad.DEACTIVATIONREASON,
        LastSavedUsername = _dOOdad.LASTUSER,
        LastSavedDateTime = _dOOdad.LASTDATE.ConvertDb2Date().AddDb2Time(_dOOdad.LASTTIME)
    };
}

Hope this helps :-)

Riegardt Steyn
  • 5,431
  • 2
  • 34
  • 49
1

Although it's old but I recommend staying away from this library. It has a serious bug that cause connection leaking, I bet the creator didn't check ADO.NET practices when coding it. Moreover, he didn't know how to deal with DBNull, thus he invented "string properties" along the side of normal properties to deal with NULL problem, turned generated code and programming model into a big mess, created more NullReferenceException when developer access normal properties which has value as null.

I collected all those problems from a 10+ years old legacy system using MyGeneration Doodads. Felt very happy that I could get rid of it at last.

If you're on the way of finding a DAC library for enterprise app, just don't pick this library.

Khoa Nguyen
  • 1,056
  • 2
  • 12
  • 20