Supposons que vous avez un fichier CSV avec la structure suivanteComment renvoyer des objets entièrement remplis à l'aide de FileHelpers pour des données partiellement complètes?
LINE1: ID,Description,Value
LINE2: 1,Product1,2
LINE3: ,,3
LINE4: ,,4
LINE5: 2,Product2,2
LINE6: ,,3
LINE7: ,,5
Avec la classe correspondante FileHelpers
définition
[DelimitedRecord(",") ]
[IgnoreFirst(1)]
public class Product
{
public int ID { get; set; }
public string Description { get; set; }
[FieldConverter(ConverterKind.Decimal)]
public decimal Val{ get; set; }
}
Comment utiliser FileHelpers, pour retourner des objets tels que chaque objet est entièrement rempli? Permettez-moi de clarifier, actuellement, le résultat de l'utilisation engine.ReadFile
ne produira que des objets des lignes 2 et 5 comme entièrement rempli, ce qui est logique puisque les champs sont vides. Toutefois, les objets des lignes 3 et 4 doivent également avoir les mêmes ID
et Description
que la ligne 1. Le champ Value
doit rester intact pour chaque ligne. Je ne suis pas sûr du bon terme pour les données, mais il semble être «partiellement normalisé».
Mon approche actuelle pour résoudre ceci est la suivante en utilisant l'événement AfterRead
. Je n'ai pas une bonne compréhension des événements, des gestionnaires d'événements, des délégués, etc., donc je cherche un moyen alternatif pour y parvenir en utilisant FileHelpers. Il semble aussi très maladroit.
// call the csv repo using the ffg lines within a console app
var repo2 = new CSVRepositoryBase<Product>();
repo2.AfterRead +=new AfterReadHandler<object>(repo2_AfterRead);
var products = repo2.Read("some file path");
public static Product PreviousRecord { get; set; }
private static void repo2_AfterRead
(EngineBase engine, FileHelpers.Events.AfterReadEventArgs<object> e)
{
var record = (Product)e.Record;
if (PreviousRecord == null)
{
PreviousRecord = new Product();
PreviousRecord.ID = record.ID;
}
if (String.IsNullOrEmpty(record.ID)) // newline record = blank row
{
record.ID = PreviousRecord.ID;
}
PreviousRecord.ID = record.ID;
}
public class CSVRepositoryBase<T> where T : class
{
// shorten for brevity
public IEnumerable<T> Read(string fileName){/*snip*/ }
#region Events
public event AfterReadHandler<object> AfterRead
{
add { engine.AfterReadRecord += value; }
remove { engine.AfterReadRecord -= value; }
}
#endregion
}
J'utilise un dll construit à partir du tronc sourceforge - de sorte que le ci-dessus devrait être la version générique 'INotifyRead <> '. Cependant, les lignes ffg 'BeforeReadEventArgs e = null; if (MustNotifyRead) {e = nouveau BeforeReadEventArgs (ceci, enregistrement, currentLine, LineNumber); skip = OnBeforeReadRecord (e); if (e.RecordLineChanged) line.ReLoad (e.RecordLine);} '(EventEngineBase.cs: 61) lève une exception 'Impossible de convertir un objet de type' Product 'en type' FileHelpers.Events.INotifyRead'1 [System. Objet]'.' –
Ahmad
@marcoMeli - ah, j'ai trouvé mon problème. J'utilisais la version non générique de la classe FileHelper 'FileHelperEngine (typeOf (Product))' au lieu de 'new FileHelper()'. –
Ahmad