I fear this is going to be a big setup for a simple question. As to complexity of the answer, I fear what I might be getting into...
I am building an application that will be used to help transform data from a source database with one table structure to a target database with a different structure. The target database will contain data already, and thus the process must be able to maintain ID-based relationships from the source when inserting to the target, where the newly-inserted items will get new IDs. Assume that each source table will be transformable to a single target table.
Minimal code, with necessary class/interface structure:
public interface IDataSetStorable { }
public class InMemoryDataSet : List<IDataSetStorable>
{
public AbstractDataEntity FindEntity(string id, Type type)
{
// The question will be about this method
return new object() as AbstractDataEntity;
}
}
public class EntityList<T> : Dictionary<string, T>, IDataSetStorable where T : AbstractDataEntity
{
public void AddEntity(T entity)
{
this.Add(entity.ID, entity);
}
}
public abstract class AbstractDataEntity
{
public string ID { get; set; }
}
public abstract class DataItem<S, T> : AbstractDataEntity { }
// There will be a set of these three classes per source DB table
public class SourceType { }
public class TargetType { }
public class TransformationType : DataItem<SourceType, TargetType> { }
InMemoryDataSet
holds the tables, represented by instances of (for example) EntityList<TransformationType>
. There will be a TransformationType
for each mapping of SourceType
to TargetType
, where each of those is likely to be a class from a DataContext. There will be one per source DB table, though many of those tables may map to a single target DB table.
The use of IDataSetStorable
as a marker interface allows for the storage of EntityList<>
s with many different subtypes within an instance of InMemoryDataSet
.
During the transformation of any item from the source DB, it can only be inserted into the target DB if we know the appropriate target-DB IDs for its foreign keys. To do this the code will find all its dependencies from the source DB and transform them BEFORE attempting to transform the item under consideration. Recursively, this should ensure that the first things inserted into the target DB have no dependencies, get their new IDs, and can then be looked up when inserting things that depend on them.
An instance of InMemoryDataSet
will provide the lookup facility, which should be passed an ID (from the source DB) and a parameter of type Type
, representing the TransformationType
which deals with transforming the type of item being looked up.
Example of that: Table1
has two fields, id
and table2_id
, the latter referencing Table2
, and its field id
. The lookup call would be (kinda pseudocode-y):
var entity = myDataSet.FindEntity([table1.table2_id], typeof(Table2TransformationType));
Then entity
should be of type Table2TransformationType
(inheriting eventually from AbstractDataEntity
), and would represent the row from Table2
with ID matching that passed to the method.
And finally, to the question:
In the FindEntity()
method, how can I find if there is an EntityList<whatever the passed type was>
present? My thought was to use something like:
foreach (var entityList in this)
{
// work out if entityList is an EntityList<passed-in type>;
}
Simple question! But I don't know how I can do this last part :(