Click or drag to resize

TypedMapper Class

Represents the base class for generated TypedMapper classes. A TypedMapper provides a type-safe implementation of an IMapper based on its meta-data.
Inheritance Hierarchy
SystemObject
  NetQuarry.DataTypedMapper

Namespace:  NetQuarry.Data
Assembly:  EAP.Mapper (in EAP.Mapper.dll) Version: 2.0.0.0 (4.6.8.0)
Syntax
public abstract class TypedMapper : IDisposable

The TypedMapper type exposes the following members.

Constructors
  NameDescription
Protected methodTypedMapper
Initializes a new instance of the object. The object is not attached to a mapper and any field access will throw an exception.
Protected methodTypedMapper(IMapper)
Initializes a new instance of the object and attaches it to the mapper
Protected methodTypedMapper(IAppContext, String, String)
Initializes a new instance of the object and attaches it to the supplied mapper. The mapper is positioned to the first row if there are rows. Use HasRecords to determine if there are valid rows in the mapper.
Top
Properties
  NameDescription
Public propertyApplication
Gets the Application context object
Public propertyDatabase
Gets the Database object attached to the contained mapper
Public propertyHasRecords
Returns true if there are one or more records in the current mapper filter, else false.
Public propertyMapper
Gets the underlying mapper
Protected propertyMapperKeyName
Returns the key name of the mapper associated with this class. This method should be overridden in the dervied class.
Public propertyMOP
Gets the MOP associated with this mapper, if any.
Public propertyRequiresClose
Gets whether or not the IMapper object was created by the TypedMapper (and therefore typically requires a close) vs. an existing IMapper object having been attached to this TypedMapper.
Public propertyTopN
Top
Methods
  NameDescription
Public methodStatic memberAttachT
Creates a new instance of the specified class (a TypedMapper dervirative) and attaches it to the mapper. You should generally not call Close on the returned TypedMapper object as that TypedMapper is a wrapper on the provided IMapper object to which it is attached (no new mapper is instantiated). Calling Close on the TypedMapper would in turn call Close on the attached mapper.
Public methodAttachExisting
Attaches an existing mapper to this class. You should generally not call Close on the this TypedMapper object as the TypedMapper will be a wrapper on the provided IMapper object to which it is attached (no new mapper is instantiated). Calling Close on the TypedMapper would in turn call Close on the attached mapper.
Public methodCloneT
Creates a cloned mapper and positions it to before the first row.
Public methodCloneAndIterateT
Creates a cloned mapper based on this object and positions it to before the first row, then iterates over each row calling the provided function. Note: If you include MapperCloneFlags you almost always want to include the 'FilterOnSelectedKeys' flag along with your provided flags. If you don't include this flag and you are operating on a mapper that is datasheet based, the checkbox selections will be ignored.
Public methodClose
Closes the underlying mapper
Public methodDelete
Calls IMapper.Delete on the underlying mapper.
Public methodDispose
Close the underlying mapper if it was created during construction of the object
Public methodEquals
Determines whether the specified Object is equal to the current Object.
(Inherited from Object.)
Protected methodFinalize
Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection.
(Inherited from Object.)
Public methodGetHashCode
Serves as a hash function for a particular type.
(Inherited from Object.)
Public methodGetKeyDisplayCollection
Returns the KeyDisplayText collection with the field captions
Public methodGetKeyDisplayCollection(KeyDisplayCollectionFlags)
Returns the KeyDisplayText collection
Public methodGetType
Gets the Type of the current instance.
(Inherited from Object.)
Public methodGetValue(String)
Get the value for the specified field. If the field is not found then an error is raised.
Public methodGetValue(String, Object, FindBehaviour)
Get the value for the specified field. The behaviour when the field is not found is dictated by the behaviour parameter.
Public methodIterateT
Iterates over this typedmapper calling the provided function
Protected methodMemberwiseClone
Creates a shallow copy of the current Object.
(Inherited from Object.)
Public methodMoveNew
Moves to a new record in the mapper.
Public methodMoveNext
Moves to the next record in the mapper.
Protected methodNullableValue
Returns null if the provided object is null or a blank/empty string, else the object itself. The purpose is to allow blank/empty strings to be treated as null for casting to a nullable type.
Public methodOnUnload
This event is fired just prior to the TypedMapper being unloaded. Derived implementations can override this event to perform appropriate cleanup.
Protected methodOpen(IAppContext, String, String, Flavors, MapperAttrs)
Creates a new mapper and moves to the first record.
Public methodStatic memberOpenT(IAppContext, String)
Public methodStatic memberOpenT(IAppContext, String, Flavors)
Public methodStatic memberOpenT(IAppContext, String, Flavors, MapperAttrs)
Protected methodOpenNew(IAppContext, String, Flavors, MapperAttrs)
Creates a new mapper and moves to a new record.
Public methodStatic memberOpenNewT(IAppContext)
Creates a new mapper and moves to a new record. The mapper is in the New state, ready to accept values. No query is performed. You must explicitly call Close or Dispose on the object after this call.
Public methodStatic memberOpenNewT(IAppContext, Flavors)
Creates a new mapper and moves to a new record. The mapper is in the New state, ready to accept values. No query is performed. You must explicitly call Close or Dispose on the object after this call.
Public methodStatic memberOpenNewT(IAppContext, Flavors, MapperAttrs)
Creates a new mapper and moves to a new record. The mapper is in the New state, ready to accept values. No query is performed. You must explicitly call Close or Dispose on the object after this call.
Protected methodOpenReader(IAppContext, String, String, Flavors, MapperAttrs, String, MapperLoadFlags)
Creates a new mapper for reading or iteration. You must call MoveNext to move to the first record.
Public methodStatic memberOpenReaderT(IAppContext, String)
Creates a new mapper for reading or iteration. You must call MoveNext to move to the first record.
Public methodStatic memberOpenReaderT(IAppContext, String, Flavors)
Public methodStatic memberOpenReaderT(IAppContext, String, Flavors, MapperAttrs)
Public methodStatic memberOpenReaderT(IAppContext, String, Flavors, MapperAttrs, String)
Public methodStatic memberOpenReaderT(IAppContext, String, Flavors, MapperAttrs, String, MapperLoadFlags)
Public methodStatic memberOpenReaderT(IAppContext, String, Flavors, MapperAttrs, String, MapperLoadFlags, Int32)
Public methodRequery
Calls Requery on the underlying mapper and position to the first record.
Public methodRequery(MapperFilter)
Sets the supplied filter and Requeries the underlying mapper and position to the first record.
Public methodSave
Calls IMapper.Save on the underlying mapper
Public methodSend(String, String)
Simple way to send a message using this mapper and a template. The mapper sets up the message, the relationships, and creates the template data appropriate from the current row before sending.
Public methodSend(String, String, NameValueCollection)
Simple way to send a message using this mapper and a template. The mapper sets up the message, the relationships, and creates the template data appropriate from the current row before sending.
Public methodSend(String, String, NameValueCollection, MessageRelationships)
Simple way to send a message using this mapper and a template. The mapper sets up the message, the relationships, and creates the template data appropriate from the current row before sending.
Public methodToString
Returns a String that represents the current Object.
(Inherited from Object.)
Top
Fields
  NameDescription
Protected field_fields
The fields collection associated with the attached mapper object
Protected field_mapper
Returns the attached mapper object to derived classes
Top
Extension Methods
  NameDescription
Public Extension MethodEqualValue
Determines if the object value is equal to another object. If the two objects are null, then this returns true. There is special handling for guid comparisons (since a guid could be a string formatted in up to 3 different ways). If the special guid handling is not performed, then the object.Equals method is used.
(Defined by EAPUtil.)
Public Extension MethodGetPageElement
Gets the PageElementInfo for the TypedMapper, if available. Note that this is simply a wrapper around the GetPageElement command.
(Defined by MapperUtils.)
Public Extension MethodIsPageElement
Determines if the TypedMapper is being rendered for the specified MOP and Name of the PageElementInfo. This method is safe to use even if the mapper is null, has no MOP, and/or has no PageElementInfo associated.
(Defined by MapperUtils.)
Top
Remarks

Generated TypedMapper-derived classes are useful when manipulating an IMapper and you would like to treat it more like a type-safe object. They are also useful as a base class for higher level business objects that you may require in your extensions. A TypedMapper has a Get and Set property for each IField defined in the mapper. If you have fields with an include flavor you may need to add a Get and Set property in your derived class as, by default, the generator will not pick up these fields. There are a number of meta-data settings that can be used to tune TypedMapper generation for a particular IMapper:

  • SkipCodeGeneration - Prevents code generation for the mapper.
  • CodeGenFlavor - Flavor (from Flavors) to set on the mapper during code generation.
  • CodeGenOptions - Options for affecting code generation at the mapper level.
  • ClassName - The name to use when generating the TypedMapper C# class. Normally used where Key a C# reserved word. By default the Key is used.
  • ForceCodeGen - Force Get/Set generation for the field (even if include is set).
  • PropertyName - The name to use for the property element in the generated TypedMapper for the corresponding IField. Normally used where Key a C# reserved word. By default the Key is used.
  • FieldCodeGenOptions - Options for affecting code generation at the field level.

You typically use a TypedMapper in your extensions. You can create a TypedMapper and attach it to the sender (an IMapper) of the event or you can use the TypedMapper derivative to create a new mapper - either for the purpose of creating a new row or reading/updating an existing one. Connecting a TypedMapper via one of the constructors or AttachT(IMapper) is very inexpensive and generally a safer way to work with a mapper. You should, however, use good judgement when creating a new instance of a mapper as a query of the operational database is required.

There are three different sets of methods for opening records using a TypedMapper:

You should call Close on any TypedMapper instantiated using one of the TypedMapper Open methods (e.g. Open, OpenReader, OpenNew), however, you should generally not call Close on TypedMappers attached to an existing IMapper using AttachT(IMapper) or AttachExisting(IMapper). Instantiating a TypedMapper using one of the Open methods instantiates a new IMapper which should be closed when the TypedMapper is no longer of use. Mappers attached to a TypedMapper, on the other hand, generally should survive the TypedMapper (e.g. when attached to a mapper that is firing the current event).

Examples

The following example shows how to use a TypedMapper derivative to get and set values in a RowBeforeUpdate(IMapper, EAPEventArgs) extension. In this case the directly generated code isn't used, rather classes derived from the generated classes. These classes are defined in a namespace different than the generated classes as well. (iLuxCars.Data vs. iLuxCars.Data.Generated).

C#
public override void RowBeforeUpdate(IMapper sender, EAPEventArgs e)
{   
    //--- Simple attach to the Offer Comparables TypedMapper derivative

    iLuxCars.Data.OfferComp oc = new iLuxCars.Data.OfferComp(sender);                       

    //--- build a row filter for a single row (the vehicle) and get the description without color
    //--- and create a mapper positioned to this row using the constructor
    //--- Note that you don't have to call close on the mapper if you create the object in a C# 'using'
    //--- construct.

    string rowFilter = string.Format("vehicle_id = '{0}'", oc.vehicle_id);
    using (iLuxCars.Data.Vehicle veh = new iLuxCars.Data.Vehicle(sender.Application, rowFilter))
    {
        string description = veh.NormalizedDescription;     //--- custom property
        oc.UpdateFromComparables(description);
    }

    //--- get important values from the TypedMapper
    //--- each property get is equivalent to the statment commented out to the right

    decimal iluxAvg = oc.ilux_avg_amt; // EAPUtil.ToDecimal(sender.Fields["ilux_avg_amt"].Value, 0);
    decimal mmrAvg = oc.mmr_avg_amt; // EAPUtil.ToDecimal(sender.Fields["mmr_avg_amt"].Value, 0);
    decimal kbbAvg = oc.kbb_amt; // EAPUtil.ToDecimal(sender.Fields["kbb_amt"].Value, 0);
    decimal targetAmt = oc.target_amt; // EAPUtil.ToDecimal(sender.Fields["target_amt"].Value, 0);
}

The following example shows a TypedMapper derived class that handles the RowBeforeInsert(IMapper, EAPEventArgs) event on the mapper.

C#
//--- The derived class. 
class VehicleRequest : iLuxCars.Data.Generated.vehicle_request
{
    public VehicleRequest(NetQuarry.Data.IMapper mapperVehicleRequest)
        : base(mapperVehicleRequest)
    {
    }

    public void OnRowBeforeInsert()
    {
        /// --- lookup the current dealer from the user id if it's missing
        IAppContext appCxt = this.Mapper.Application;

        if (string.IsNullOrEmpty(this.dealer_id.ToString()))
        {
            string dealerID = iLuxCars.Common.EmailHelper.GetUserDealerID(appCxt);
            this.dealer_id = new Guid(dealerID);
        }
    }
}

//--- The extension class calling the TypedMapper Business Object.
public class XExt : NetQuarry.Data.MapperExtensionKernel
{
    public XExt() { }

    public override void RowBeforeInsert(IMapper sender, EAPEventArgs e)
    {
        iLuxCars.Data.VehicleRequest vehReq = new iLuxCars.Data.VehicleRequest(sender);
        vehReq.OnRowBeforeInsert();
    }
}

The following example creates a new TypedMapper derivative, sets some values, and saves the record.

C#
//--- create a new instance of our subclassed vehicle TypedMapper and attach it to the mapper passed in

Vehicle     typedVehicle = new Vehicle(mapperVehicle);

//--- call the .NormalizedDescription on our subclass

string      normalizedDescription = typedVehicle.NormalizedDescription;

//--- Create a new instance of our subclassed offer_comp (TypedMapper). This calls a 
//--- helper method to create a mapper and move it to a new record, read for setting values.

using (OfferComp oc = OfferComp.OpenNew(appCxt))
{
    //--- Set the offer_id (FK) from the param

    oc.offer_id = new Guid(offerID);

    //--- Set the vehicle_id now (this isn't actually necessary as this is really a field from another 
    //--- table populated from the view.)

    oc.vehicle_id = typedVehicle.vehicle_id;

    //--- call our custom method to update the values from comparables in the db

    oc.UpdateFromComparables(normalizedDescription);

    //--- save

    oc.Save();

    /// --- It is safe to call oc.Close() but not necessary if you
    /// --- are inside a using block.
}

Generating TypedMappers

The C# source code for TypedMappers is generated using the platform's manually-invoked CodeGen facility. The CodeGen program creates a C# class for each IMapper definition. Typically all the generated C# classes are contained in the project's TypedMapeprs.cs file.

To generate typed mappers you run the command line utility EAP.Tools.CodeGen.EXE installed in the <application root>/bin folder. The utility takes the following arguments (the first argument (-AppID) is required):

  1. -AppID:<appid> - the ID for your application.
  2. -CamelCase - (optional) include this to convert property names to a CamelCase representation. By default, for each IField in the mapper the property name is the same as the Key.
  3. -NullableNumerics - (optional) include this to declare the numeric field properties as Nullable (e.g., int fields will be declared as int?). By default, numeric properties are defined as their value types and 0 (or false) is returned if the value is null.
  4. -NoNullStrings - (optional) include this to force string properties to return an empty string instead of null when the field value is null. By default, null values are returned as null strings.
  5. -Docs - (optional) include this to generate more complete in-line comment headers for documentation generation.
You must create a config section in the EAP.Tools.CodeGen.exe.config with the options. Example:
<configSections>
    <section name="IssueTrak" type="System.Configuration.NameValueSectionHandler" />
</configSections>

<IssueTrak>
    <!-- connection strings -->
    <add key="repository_connect" value="Provider=SQLOLEDB;Data Source=.;Initial Catalog=issues_meta;Integrated Security=SSPI" />    
    <add key="IssueTrak_connect" value="Provider=SQLOLEDB;Data Source=.;Initial Catalog=issues_data;Integrated Security=SSPI" />

    <!-- optional, normally set by the web application context -->
    <add key="RootPath" value="c:\inetpub\wwwroot" />
    <add key="RootURL" value="http://localhost" />

    <!-- full path to the file to be generated -->
    <add key="GeneratedFileName" value="C:\NetQuarry\IssueTrak\Source\Data\Generated\TypedMappers.cs" />
    <!-- namespace to use for the generated TypedMapper classes -->
    <add key="Namespace" value="IssueTrak.Data" />
</IssueTrak>

Example:

SET APP_KEY=IssueTrak
EAP.Tools.CodeGen -AppID:%APP_KEY% -CamelCase -NoNullStrings

Using the generated classes

You should not write code or otherwise change the generated classes, rather you should dervive a class from a generated class and add application specific logic to the derived class. The following class derives from the generated base and adds a method that is to be called during the RowBeforeInsert event in an extension (in the second block).

public class Dealer : iLuxCars.Data.Generated.dealer<Dealer>
{
    public Dealer() : base() {}
    public Dealer(NetQuarry.Data.IMapper mapperDealer) : base(mapperDealer) { }       

    public void OnBeforeInsert()
    {
        string rowFilter = base.Fields.dealership_nm.BuildFilter();
        rowFilter += "" AND "" + base.Fields.postal_code.BuildFilter();
        using (Dealership boDealership = Dealership.Open(this.Application, rowFilter))
        {
            if (boDealership.HasRecords)
                this.dealership_id = boDealership.dealership_id;
        }
    }
}

public override void RowBeforeInsert(IMapper sender, EAPEventArgs e)
{            
    iLuxCars.Data.Dealer boDealer = new iLuxCars.Data.Dealer(sender);
    boDealer.OnBeforeInsert();
}
See Also