genericizing conformance checks when importing data
I am working on an import assistant (C# .NET 4) between 2 MS Access databases and I need to implement a mechanism to ensure data consistency.
Example:
Import persons.
Problem:
The columns from the person tables have different column sizes.
Source Table: Address column size = 50;
Destination Table: Address column size = 30;
When we try to import a person with a Address larger than 30 chars a problem appears.
Desired solution:
When the previous problem appears a dialog needs to be shown where the user can redefine or truncate the value to correspond to the require length.
Import function looks something like this
private static void ImportPerson()
{
var sourcePerson = sourcePerson.GetObject()开发者_如何学Go;
if (sourcePerson == null)
return;
var person = new MyPerson();
person.Address.Value = sourcePerson.Address;
person.Company.Value = sourcePerson.Company;
person.Save();
}
I have metadata information stored in my objects witch allows me to access the column size of my destination columns.
person.Address.ColumnSize
So I can do something like this after filling business objects with the new values.
if (person.Address.ColumnSize.CompareTo(person.Address.Value.Length)) < 0
// show dialog ...
Unfortunately this means checking all the properties (Address, Company... and other) individually.
I am looking for a more generic approach where I don't need to check every property individually.
Any ideas, suggestions, thoughts would be highly appreciated.
Presumably, the members of your class (Adress, Company, etc) are all objects of the same type, since they seem to have consistent properties that you're using for metadata. Add a method to your MyPerson
class to provide access to its properties by iterating, e.g.
class MyPerson {
public IEnumerable<MemberClass> Properties
{
get {
yield return Adress;
yield return Company;
...
}
}
...
}
Then
foreach (MemberClass prop in person.Properties) {
if (prop.ColumnSize.CompareTo(prop.Value.Length) < 0)
// show dialog ...
}
}
It would probably also make sense to collect all the failures in a list and just show a single dialog for the record, to make life easier for the user.
Have you considered taking your properties and having them reference a Dictionary of IMetaData?
private Dictionary<string, IMetaData> metaData;
public PersonAddress Address {
get { return (PersonAddress)metaData["Address"]; }
set { metaData["Address"] = value; }
}
Then you can process each key, run your checks, and still keep the same interface.
public void Process() {
foreach(var key in metaData.Keys) {
var property = metaData[key];
// Check the property...
}
}
That should work. However it might end up showing feature envy in which case you would want to take the metaData dictionary and make your own class for it. But that is outside the scope of your question.
精彩评论