我希望使用动态类型对象来写入CSV文件。
我收到了' CsvHelper.CsvWriterException'在CsvWriter.WriteObject方法中包含以下消息:"没有为类型' WpmExport.DynamicEntry'映射属性。'
以下是我尝试使用的课程:
public class DynamicEntry : DynamicObject
{
private Dictionary<string, object> dictionary = new Dictionary<string, object>();
public override bool TryGetMember(
GetMemberBinder binder, out object result)
{
string name = binder.Name.ToLower();
return dictionary.TryGetValue(name, out result);
}
public override bool TrySetMember(
SetMemberBinder binder, object value)
{
dictionary[binder.Name.ToLower()] = value;
return true;
}
public override IEnumerable<string> GetDynamicMemberNames()
{
return dictionary.Keys.AsEnumerable();
}
}
任何有想法或工作实例的人? http://joshclose.github.io/CsvHelper/处的文档暗示可能但不提供任何指导。
TIA
答案 0 :(得分:4)
该功能尚不存在。您可以写dynamic
但不能DynamicObject
。您可以在此处查看主题的主题。 https://github.com/JoshClose/CsvHelper/issues/187
当功能实施后,我将使用其所在的版本更新答案。
<强>更新强>
此功能将在3.0中提供。您目前可以从NuGet试用3.0-beta。
答案 1 :(得分:2)
因为我不能等待3.0版(并且CsvHelper.Excel支持它),所以我找到了一个临时解决方案。
获得要导出的课程:
public partial class EntryReportInventory
{
public Guid DeviceId { get; set; }
[ReportProperty]
public string DeviceName { get; set; }
public Dictionary<string, object> InventoryValues { get; set; }
public EntryReportInventory(Device device, Dictionary<string, object> inventoryValues)
{
this.DeviceId = device.Id;
this.DeviceName = device.Name;
this.InventoryValues = inventoryValues;
}
}
创建Mapper:
Type genericClass = typeof(DefaultCsvClassMap<>);
Type constructedClass = genericClass.MakeGenericType(typeof(EntryReportInventory));
return (CsvClassMap)Activator.CreateInstance(constructedClass);
现在神奇了。我迭代所有属性。
foreach (PropertyInfo property in mapping)
{
...
if (isInventoryReportBaseType && typeof(Dictionary<string, object>).IsAssignableFrom(property.PropertyType))
{
var dataSource = (ReportInventoryBase)Activator.CreateInstance(entityType, dbContext);
foreach (var item in dataSource.ColumnNameAndText)
{
var columnName = item.Key;
var newMap = new CsvPropertyMap(property);
newMap.Name(columnName);
newMap.TypeConverter(new InventoryEntryListSpecifiedTypeConverter(item.Key));
customMap.PropertyMaps.Add(newMap);
}
...
}
我的转换器是:
public class InventoryEntryListSpecifiedTypeConverter : CsvHelper.TypeConversion.ITypeConverter
{
private string indexKey;
public InventoryEntryListSpecifiedTypeConverter(string indexKey)
{
this.indexKey = indexKey;
}
public bool CanConvertFrom(Type type)
{
return true;
}
public bool CanConvertTo(Type type)
{
return true;
}
public object ConvertFromString(TypeConverterOptions options, string text)
{
throw new NotImplementedException();
}
public string ConvertToString(TypeConverterOptions options, object value)
{
var myValue = value as Dictionary<string, object>;
if (value == null || myValue.Count == 0) return null;
return myValue[indexKey] + "";
}
}
不知道为什么,但它可以多次传递相同的属性。 那就是:) 您只需要在之前有一个列表(此处:dataSource.ColumnNameAndText,从外部源填充)以标识列/值。