-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rollback part of commit 7dbb3fe710466ec2f573f81e19c7130ec1c7a365 #2273
Comments
The idea is, you should never have a Does this sound reasonable? As far as the |
That would work for me. Can you push a fix today |
Working on it right now. |
I have a dilemma. The way things work is row by row. That means you call The issue here is that I think the correct solution here is to have csv.Read();
csv.ReadHeader();
while (csv.Read())
{
var record = csv.GetRecord<Foo>();
} The other option is to have What do you think? |
I think if CsvConfiguration specifies there is a header record, it should do it for you. ReadHeader should add a remark that it should only be used for highly customized or niche scenarios, and is primarily intended for internal use when CsvConfiguration.HasHeaderRecord is true. Otherwise, what is the point of the CsvConfiguration.HasHeaderRecord property? |
Only used for |
Then ReadHeader should add a remarks that it requires CsvConfiguration.HasHeaderRecord to be true, but allows the consumer to directly read. And yes, your Read fix should work. In my use case, we read and validate one row at a time with FluentValidation, so that we can parse a batch of records in really large CSV files, validate it, and save to a db only the good rows and report the bad rows. Otherwise I'm not certain we would need to read one row at a time. A lot of financial data is zipped csv files, so we deflate, which is memory intensive, and to avoid running out of memory, as well as scaling db insert/update/delete operations, we process in batches of 1000. |
@JoshClose This was my generic solution based on your last comment - do you think this is OK? - at a practical level, it doesn't make a ton of sense given how the code for GetRecord reads (it implies it should read the header for you) - but the below code passes 3 different important test scenarios:
using (var streamReader = new StreamReader(request.Stream))
{
using (var csvReader = new CsvReader(streamReader, request.Configuration))
{
csvReader.Context.RegisterClassMap<TMap>();
var stopwatch = Stopwatch.StartNew();
if (csvReader.Configuration.HasHeaderRecord)
{
csvReader.Read();
csvReader.ReadHeader();
}
if (csvReader.Read())
{
var importLine = csvReader.GetRecord<TResult>();
if (importLine != null)
{
if (!IsValid(request, importLine, csvReader.Context, out var error))
{
errors.Add(error);
}
else
{
results.Add(importLine);
}
}
}
return new CsvBatchParserResponse<TResult>
{
Results = results,
Errors = errors,
ParseTime = stopwatch.Elapsed
};
} |
Describe the bug
I don't know why the code is now throwing an exception when it used to return null - the commit where this occurred just says it was done to remove nullability - but why when that is very useful. There is no clear use case for this behavior, and it causes an exception to be thrown on an empty file, which is highly non-desirable behavior.
In any event, the lack of migration guide since v30 to now is also making upgrading difficult and questionable. We're on v31 but given the other bug I filed, I'm not planning to upgrade further.
To Reproduce
7dbb3fe#diff-e1cbba681f102065fada3e91fecbfbc458195a01974189a3483f75e72137afdaL733-L736
Fails with the following:
Empty.csv in CsvHelperBug.csproj
SampleMap.cs
SampleLine.cs
CsvHelperBug/Test.cs
Additionally, the following fails with "No header record was found" (wtf?):
Expected behavior
Roll this back! It doesn't make any sense in the perfectly valid scenario where there are no rows.
Screenshots
n/a
Additional context
n/a
The text was updated successfully, but these errors were encountered: