/// <summary> /// Writes the header record from the given properties. /// </summary> /// <param name="type">The type of the record.</param> protected virtual void WriteHeader(Type type) { if (configuration.Properties.Count == 0) { configuration.AttributeMapping(type); } var properties = new CsvPropertyMapCollection(); properties.AddRange(configuration.Properties); foreach (var reference in configuration.References) { properties.AddRange(reference.ReferenceProperties); } foreach (var property in properties) { if (!property.IgnoreValue) { WriteField(property.NameValue); } } NextRecord(); hasHeaderBeenWritten = true; }
/// <summary> /// Writes the header record from the given properties. /// </summary> /// <param name="type">The type of the record.</param> public virtual void WriteHeader(Type type) { if (type == null) { throw new ArgumentNullException("type"); } if (!configuration.HasHeaderRecord) { throw new CsvWriterException("Configuration.HasHeaderRecord is false. This will need to be enabled to write the header."); } if (hasHeaderBeenWritten) { throw new CsvWriterException("The header record has already been written. You can't write it more than once."); } if (hasRecordBeenWritten) { throw new CsvWriterException("Records have already been written. You can't write the header after writing records has started."); } if (configuration.Properties.Count == 0) { configuration.AttributeMapping(type); } var properties = new CsvPropertyMapCollection(); properties.AddRange(configuration.Properties); foreach (var reference in configuration.References) { properties.AddRange(reference.ReferenceProperties); } foreach (var property in properties) { if (!property.IgnoreValue) { WriteField(property.NameValue); } } NextRecord(); hasHeaderBeenWritten = true; }
/// <summary> /// Writes the header record from the given properties. /// </summary> protected virtual void WriteHeader <T>() where T : class { if (configuration.Properties.Count == 0) { configuration.AttributeMapping <T>(); } foreach (var property in configuration.Properties) { if (!property.IgnoreValue) { WriteField(property.NameValue); } } NextRecord(); hasHeaderBeenWritten = true; }
/// <summary> /// Gets the function delegate used to populate /// a custom class object with data from the reader. /// </summary> /// <typeparam name="T">The <see cref="Type"/> of object that is created /// and populated.</typeparam> /// <returns>The function delegate.</returns> protected virtual Func <CsvReader, T> GetReadRecordFunc <T>() where T : class { var type = typeof(T); if (!recordFuncs.ContainsKey(type)) { var bindings = new List <MemberBinding>(); var recordType = typeof(T); var readerParameter = Expression.Parameter(GetType(), "reader"); // If there is no property mappings yet, use attribute mappings. if (configuration.Properties.Count == 0) { configuration.AttributeMapping <T>(); } foreach (var propertyMap in configuration.Properties) { if (propertyMap.IgnoreValue) { // Skip ignored properties. continue; } if (propertyMap.TypeConverterValue == null || !propertyMap.TypeConverterValue.CanConvertFrom(typeof(string))) { // Skip if the type isn't convertible. continue; } var index = propertyMap.IndexValue < 0 ? GetFieldIndex(propertyMap.NameValue) : propertyMap.IndexValue; if (index == -1) { // Skip if the index was not found. continue; } // Get the field using the field index. var method = GetType().GetProperty("Item", new[] { typeof(int) }).GetGetMethod(); Expression fieldExpression = Expression.Call(readerParameter, method, Expression.Constant(index, typeof(int))); // Convert the field. var typeConverterExpression = Expression.Constant(propertyMap.TypeConverterValue); var convertMethod = Configuration.UseInvariantCulture ? "ConvertFromInvariantString" : "ConvertFromString"; fieldExpression = Expression.Call(typeConverterExpression, convertMethod, null, fieldExpression); fieldExpression = Expression.Convert(fieldExpression, propertyMap.PropertyValue.PropertyType); bindings.Add(Expression.Bind(propertyMap.PropertyValue, fieldExpression)); } var body = Expression.MemberInit(Expression.New(recordType), bindings); var func = Expression.Lambda <Func <CsvReader, T> >(body, readerParameter).Compile(); recordFuncs[type] = func; } return((Func <CsvReader, T>)recordFuncs[type]); }
public void FieldAttributeNameTest() { var config = new CsvConfiguration(); config.AttributeMapping<TestClass>(); Assert.Equal( 4, config.Properties.Count ); Assert.Equal( "Guid Column", config.Properties[0].NameValue ); Assert.Equal( "Int Column", config.Properties[1].NameValue ); Assert.Equal( "String Column", config.Properties[2].NameValue ); Assert.Equal( "NotUsedColumn", config.Properties[3].NameValue ); }
public void FieldAttributeMultipleNamesTest() { var config = new CsvConfiguration(); config.AttributeMapping<TestMultipleNamesClass>(); Assert.Equal( 2, config.Properties.Count ); Assert.Equal( 2, config.Properties[0].NamesValue.Length ); Assert.Equal( "Id1", config.Properties[0].NamesValue[0] ); Assert.Equal( "Id2", config.Properties[0].NamesValue[1] ); Assert.Equal( "Name1", config.Properties[1].NamesValue[0] ); Assert.Equal( "Name2", config.Properties[1].NamesValue[1] ); }
public void FieldAttributeIndexTest() { var config = new CsvConfiguration(); config.AttributeMapping<TestClass>(); Assert.Equal( 4, config.Properties.Count ); Assert.Equal( 1, config.Properties[0].IndexValue ); Assert.Equal( 2, config.Properties[1].IndexValue ); Assert.Equal( 3, config.Properties[2].IndexValue ); Assert.Equal( -1, config.Properties[3].IndexValue ); }
public void FieldAttributeIgnoreTest() { var config = new CsvConfiguration(); config.AttributeMapping<TestClass>(); Assert.Equal( 4, config.Properties.Count ); Assert.False( config.Properties[0].IgnoreValue ); Assert.True( config.Properties[1].IgnoreValue ); Assert.False( config.Properties[2].IgnoreValue ); Assert.False( config.Properties[3].IgnoreValue ); }
public void FieldAttributeTypeConverterTest() { var config = new CsvConfiguration(); config.AttributeMapping<TestClass>(); Assert.AreEqual( 4, config.Properties.Count ); Assert.IsInstanceOfType( config.Properties[0].TypeConverterValue, typeof( StringConverter ) ); Assert.IsInstanceOfType( config.Properties[1].TypeConverterValue, typeof( Int32Converter ) ); Assert.IsInstanceOfType( config.Properties[2].TypeConverterValue, typeof( Int16Converter ) ); Assert.IsInstanceOfType( config.Properties[3].TypeConverterValue, typeof( StringConverter ) ); }
public void FieldAttributeTypeConverterTest() { var config = new CsvConfiguration(); config.AttributeMapping<TestClass>(); Assert.Equal( 4, config.Properties.Count ); Assert.IsType<StringConverter>( config.Properties[0].TypeConverterValue ); Assert.IsType<Int32Converter>( config.Properties[1].TypeConverterValue ); Assert.IsType<Int16Converter>( config.Properties[2].TypeConverterValue ); Assert.IsType<StringConverter>( config.Properties[3].TypeConverterValue ); }
public void FieldAttributeMultipleNamesTest() { var config = new CsvConfiguration(); config.AttributeMapping <TestMultipleNamesClass>(); Assert.AreEqual(2, config.Properties.Count); Assert.AreEqual(2, config.Properties[0].NamesValue.Length); Assert.AreEqual("Id1", config.Properties[0].NamesValue[0]); Assert.AreEqual("Id2", config.Properties[0].NamesValue[1]); Assert.AreEqual("Name1", config.Properties[1].NamesValue[0]); Assert.AreEqual("Name2", config.Properties[1].NamesValue[1]); }
public void FieldAttributeTypeConverterTest() { var config = new CsvConfiguration(); config.AttributeMapping <TestClass>(); Assert.AreEqual(4, config.Properties.Count); Assert.IsInstanceOfType(config.Properties[0].TypeConverterValue, typeof(StringConverter)); Assert.IsInstanceOfType(config.Properties[1].TypeConverterValue, typeof(Int32Converter)); Assert.IsInstanceOfType(config.Properties[2].TypeConverterValue, typeof(Int16Converter)); Assert.IsInstanceOfType(config.Properties[3].TypeConverterValue, typeof(StringConverter)); }
private void WriteRecords(System.IO.TextWriter textWriter) { var csvConfiguration = new CsvConfiguration() { Quote = '\"', QuoteAllFields = false }; var writer = new CsvWriter(textWriter, csvConfiguration); { if (csvConfiguration.Properties.Count == 0) { if (this.properties == null) { csvConfiguration.AttributeMapping <T>(); } else { csvConfiguration.AttributeMapping <T>(); var q = from p in csvConfiguration.Properties where !this.properties.Any(pi => pi.Name == p.PropertyValue.Name) select p; foreach (var item in q.ToList()) { csvConfiguration.Properties.Remove(item); } } } foreach (var p in csvConfiguration.Properties) { writer.WriteField(p.NameValue); } writer.NextRecord(); foreach (var record in records) { foreach (var p in csvConfiguration.Properties) { var value = p.PropertyValue.GetValue(record, null); if (value == null) { writer.WriteField("NULL", false); } else if (value is DateTime) { writer.WriteField(((DateTime)value).ToString(p.FormatValue)); } else if (value is int) { writer.WriteField(value.ToString()); } else if (value is bool) { writer.WriteField(((bool)value == true ? 1 : 0).ToString()); } else { writer.WriteField(value, p.TypeConverterValue); } } writer.NextRecord(); } } }
/// <summary> /// Gets the function delegate used to populate /// a custom class object with data from the reader. /// </summary> /// <typeparam name="T">The <see cref="Type"/> of object that is created /// and populated.</typeparam> /// <returns>The function delegate.</returns> protected virtual Func <CsvReader, T> GetReadRecordFunc <T>() where T : class { var recordType = typeof(T); if (!recordFuncs.ContainsKey(recordType)) { var bindings = new List <MemberBinding>(); var readerParameter = Expression.Parameter(GetType(), "reader"); // If there is no property mappings yet, use attribute mappings. if (configuration.Properties.Count == 0) { configuration.AttributeMapping <T>(); } AddPropertyBindings(readerParameter, configuration.Properties, bindings); foreach (var referenceMap in configuration.References) { var referenceReaderParameter = Expression.Parameter(GetType(), "reader2"); var referenceBindings = new List <MemberBinding>(); AddPropertyBindings(referenceReaderParameter, referenceMap.ReferenceProperties, referenceBindings); var referenceBody = Expression.MemberInit(Expression.New(referenceMap.Property.PropertyType), referenceBindings); var referenceFunc = Expression.Lambda(referenceBody, referenceReaderParameter); var referenceCompiled = referenceFunc.Compile(); var referenceCompiledMethod = referenceCompiled.GetType().GetMethod("Invoke"); Expression referenceObjectExpression = Expression.Call(Expression.Constant(referenceCompiled), referenceCompiledMethod, Expression.Constant(this)); bindings.Add(Expression.Bind(referenceMap.Property, referenceObjectExpression)); } var body = Expression.MemberInit(Expression.New(recordType), bindings); var func = Expression.Lambda <Func <CsvReader, T> >(body, readerParameter).Compile(); recordFuncs[recordType] = func; // This is the expression that is built: // // Func<CsvReader, T> func = reader => // { // foreach( var propertyMap in configuration.Properties ) // { // string field = reader[index]; // object converted = TypeConverter.ConvertFromString( field ); // T convertedAsType = converted as T; // property.Property = convertedAsType; // } // // foreach( var referenceMap in configuration.References ) // { // Func<CsvReader, referenceMap.Property.PropertyType> func2 = reader2 => // { // foreach( var property in referenceMap.ReferenceProperties ) // { // string field = reader[index]; // object converted = TypeConverter.ConvertFromString( field ); // T convertedAsType = converted as T; // property.Property = convertedAsType; // } // }; // reference.Property = func2( (CsvReader)this ); // } // }; // // The func can then be called: // // func( CsvReader reader ); // } return((Func <CsvReader, T>)recordFuncs[recordType]); }
/// <summary> /// Creates the read record func for the given type if it /// doesn't already exist. /// </summary> /// <param name="recordType">Type of the record.</param> /// <param name="expressionCompiler">The expression compiler.</param> protected virtual void CreateReadRecordFunc(Type recordType, Func <Expression, ParameterExpression, Delegate> expressionCompiler) { if (recordFuncs.ContainsKey(recordType)) { return; } var bindings = new List <MemberBinding>(); var readerParameter = Expression.Parameter(typeof(ICsvReader), "reader"); // If there is no property mappings yet, use attribute mappings. if (configuration.Properties.Count == 0) { configuration.AttributeMapping(recordType); } AddPropertyBindings(readerParameter, configuration.Properties, bindings); foreach (var referenceMap in configuration.References) { var referenceReaderParameter = Expression.Parameter(typeof(ICsvReader), "reader2"); var referenceBindings = new List <MemberBinding>(); AddPropertyBindings(referenceReaderParameter, referenceMap.ReferenceProperties, referenceBindings); var referenceBody = Expression.MemberInit(Expression.New(referenceMap.Property.PropertyType), referenceBindings); var referenceFunc = Expression.Lambda(referenceBody, referenceReaderParameter); var referenceCompiled = referenceFunc.Compile(); var referenceCompiledMethod = referenceCompiled.GetType().GetMethod("Invoke"); Expression referenceObjectExpression = Expression.Call(Expression.Constant(referenceCompiled), referenceCompiledMethod, Expression.Constant(this)); bindings.Add(Expression.Bind(referenceMap.Property, referenceObjectExpression)); } var constructorExpression = configuration.Constructor ?? Expression.New(recordType); var body = Expression.MemberInit(constructorExpression, bindings); var func = expressionCompiler(body, readerParameter); recordFuncs[recordType] = func; #region This is the expression that is built: // // Func<CsvReader, T> func = reader => // { // foreach( var propertyMap in configuration.Properties ) // { // string field = reader[index]; // object converted = ITypeConverter.ConvertFromString( field ); // T convertedAsType = converted as T; // property.Property = convertedAsType; // } // // foreach( var referenceMap in configuration.References ) // { // Func<CsvReader, referenceMap.Property.PropertyType> func2 = reader2 => // { // foreach( var property in referenceMap.ReferenceProperties ) // { // string field = reader[index]; // object converted = ITypeConverter.ConvertFromString( field ); // T convertedAsType = converted as T; // property.Property = convertedAsType; // } // }; // reference.Property = func2( (CsvReader)this ); // } // }; // // The func can then be called: // // func( CsvReader reader ); // #endregion This is the expression that is built: }