我正在使用FileHelperAsyncEngine<T>
类(来自FileHelpers NuGet package)从MVC应用程序流式传输非常大的CSV文件。
我们要将许多不同类型的数据传输到CSV,我正在寻找一种设置默认分隔符的方法,以避免使用[DelimitedRecord(",")]
属性修饰我的数据类。
我知道我可以使用CsvEngine
类,但性能至关重要,异步版本的速度要快几个数量级。
我是否遗漏了某些内容或无法设置默认记录分隔符?
答案 0 :(得分:1)
我想毕竟有可能发生任何事情。这很难看,但是这个版本使用反射来创建一个带有属性的新代理类。
namespace FileHelpersConsoleApplication1
{
public class Program
{
public class Record
{
public string Id;
public string Name;
}
public static void Main(string[] args)
{
var type = typeof(Record);
var defaultDelimiter = ",";
var aName = type.Assembly.GetName();
var ab = AppDomain.CurrentDomain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Run);
var mb = ab.DefineDynamicModule(aName.Name);
var tb = mb.DefineType(type.Name + "Proxy", TypeAttributes.Public, type);
var attrCtorParams = new Type[] { typeof(string) };
var attrCtorInfo = typeof(DelimitedRecordAttribute).GetConstructor(attrCtorParams);
var attrBuilder = new CustomAttributeBuilder(attrCtorInfo, new object[] { defaultDelimiter });
tb.SetCustomAttribute(attrBuilder);
var newType = tb.CreateType();
var engine = new FileHelperAsyncEngine(newType);
//var options = engine.Options as DelimitedRecordOptions;
//options.Delimiter = "|"; // you can still change delimiter if you need to
string src = "abc,JohnDoe";
using (engine.BeginReadString(src))
{
var enumerator = (engine as IEnumerable<object>).GetEnumerator();
enumerator.MoveNext();
var currentRecord = enumerator.Current as Record;
Assert.AreEqual("abc", currentRecord.Id);
Assert.AreEqual("JohnDoe", currentRecord.Name);
}
Console.ReadKey();
}
}
}
答案 1 :(得分:-1)
您可以将engine.Options转换为DelimitedRecordOptions
并更改分隔符。像这样:
public class Program
{
[DelimitedRecord(",")] // you need to specify some delimiter, even if you change it later...
public class Record
{
public string Id;
public string Name;
}
static void Main(string[] args)
{
var engine = new FileHelperAsyncEngine<Record>();
var options = engine.Options as DelimitedRecordOptions;
options.Delimiter = "|"; // change the delimiter to vertical bar
// test
string src = "abc|JohnDoe";
using (engine.BeginReadString(src))
{
var enumerator = (engine as IEnumerable<Record>).GetEnumerator();
enumerator.MoveNext();
Assert.AreEqual("abc", enumerator.Current.Id);
Assert.AreEqual("JohnDoe", enumerator.Current.Name);
}
Console.ReadKey();
}
}