JoshClose / CsvHelper

Library to help reading and writing CSV files
http://joshclose.github.io/CsvHelper/
Other
4.78k stars 1.07k forks source link

Examples for .Convert in ClassMap? #1710

Closed RPM1984 closed 3 years ago

RPM1984 commented 3 years ago

Hi there! 👋

I'm trying to migrate my code from v12.x to v23, and having trouble with this code:

private class MyMap : ClassMap<MyClass>
{
    public MyMap()
    {
        Map(x => x.SomeEnum)
            .ConvertUsing(row => row[0].StartsWith("/foo") ? MyEnum.MemberOne : MyEnum.MemberTwo);
    }
}

I know i need to somehow use the .Convert method, but i can't see how to use it.

Seems like documentation is missing here, and i looked through the repo and couldn't find any examples either.

Could you please point me in the right direction, thanks!

JoshClose commented 3 years ago
private class MyMap : ClassMap<MyClass>
{
    public MyMap()
    {
        Map(x => x.SomeEnum)
            .Convert(args => args.Row[0].StartsWith("/foo") ? MyEnum.MemberOne : MyEnum.MemberTwo);
    }
}
JoshClose commented 3 years ago

All the delegates now take in a single structs args instead of parameters. This should help people know what values are available and what they're used for.

RPM1984 commented 3 years ago

Thanks for the quick reply @JoshClose ! Keep up the good work 👏

RPM1984 commented 3 years ago

hey @JoshClose , sorry to bug you.. but, example you gave seems to be failing on .NET Core 2.2:

error CS1061: 'ConvertToStringArgs' does not contain a definition for 'Row' and no accessible extension method 'Row' accepting a first argument of type 'ConvertToStringArgs' could be found (are you missing a using directive or an assembly reference?)

my project is a .net core 2.2 project. is above not supported in .net core 2.2? (or.. IOW, is .NET Core 2.2 not supported for v23, in which case I'm not sure if the 'targeting' is correct?) thanks!

JoshClose commented 3 years ago

.NET Core 2.2 hasn't been supported by Microsoft since 2019-12-23. If you have this issue in 2.1 or 3.1, let me know and I'll figure it out.

RPM1984 commented 3 years ago

@JoshClose thanks, fair point. i'll downgrade the library then for now..

side note: the version i'm trying to upgrade to supports NS2.0, which .net core 2.2 is compliant for, so i guess my question is: if it's not supported, why did it let me install it?

JoshClose commented 3 years ago

No clue. https://dotnet.microsoft.com/download/dotnet

image

RPM1984 commented 3 years ago

@JoshClose I think you misunderstood. That page is Microsoft's support for various flavours of .net. I understand which ones are/aren't supported in that sense.

My question was: why did CsvHelper let me install v23 onto a .netcore2.2 app, if you're saying you don't support it? So if you don't want to support it, shouldn't you change your netstandard targeting strategy? Unless I'm missing something, in which case I'm keen to learn! Thanks

JoshClose commented 3 years ago

Oh, I see. I have no control over that, as far as I know. The NuGet functionality in Visual Studio/dotnet handles that. If you're using an unsupported version of .NET, NuGet will still install the best version for it.

These are the framework CsvHelper builds for.

<TargetFrameworks>net50;netstandard2.1;netstandard2.0;net47;net45</TargetFrameworks>

Everything else is handle by NuGet.

RPM1984 commented 3 years ago

@JoshClose i think (maybe i'm wrong) that you need to change your <TargetFrameworks> to remove netstandard2.0.

See here image

.NET Core 2.x implements NS 2.0:

The following table lists the minimum implementation versions that support each .NET Standard version. That means that later versions of a listed implementation also support the corresponding .NET Standard version. For example, .NET Core 2.1 and later versions support .NET Standard 2.0 and earlier versions.

In other words, i believe you need to figure out the minimum version of .NET you want to support, and reflect that in your targeting.

AFAIK you can't support .net 2.1, and not .net 2.2. it's 2.x or nothing.

So, i'd suggest:

Sorry if I'm being too forward, etc... it's totally up to you! I'm just always trying to make sure i understand how NS targeting works for libs, for my own learning.

JoshClose commented 3 years ago

It's the other way around. netstandard2.0 works with netcoreapp2.0 and above. netstandard is a minimal set of features that are guaranteed to be in a framework. The framework itself may have a lot more. It's a way for class libraries to be re-usable across frameworks. It's basically a better version of the portable class library, if you ever used those in the past.

I'm not going to support versions of .NET that are no longer supported by Microsoft. There are bug fixes/patches that are released that don't go into those versions. If you can verify the issue you are having happens on netcoreapp2.1 or netcoreapp3.1, I'd be more than happy to look into it.

If you run into any sort of issue, Microsoft will not support 2.2 either.

Out of curiosity, why are you using an out of support version instead of an LTS version?

RPM1984 commented 3 years ago

I'm still a bit confused by the behavior here. If i pull down a package, it shouldn't error because I'm on a .NET version that it doesn't support, rather it shouldn't allow me to install it in the first place -> that's the normal behavior I've seen. What's happening here I've never seen. But it's ok.. i'll just move on.

Regarding your q RE why we are on .NET 2.2, it's tough to remember, but i believe we were on .NET Core 2.1, then we decided to upgrade to 2.2 (because, why not? it's newer..), but then when .NET Core 3.1 came out, i believe 2.2 was given a pretty short EOL date.

So i think our mistake was upgrading to something non LTS. We just haven't had time to migrate. But when we do, we'll go straight to the highest current LTS (.NET 5).

Anyway, thanks for being responsive on this thread. I think we've reached an impass for now. I just won't upgrade CsvHelper until we migrate to .NET 5.

Thanks!

JoshClose commented 3 years ago

I think the issue is a bug in .NET Core 2.2 (unless you can confirm it in a different supported framework). There's nothing I can do about that.

I don't think there is a way for me to block a version of the library from being installed. I need to keep netstandard2.0 to support netcoreapp2.1.

You could try referencing a different version of CsvHelper from the directory that NuGet installs into to see if another will work. I believe netstandard2.0 is the only one that works with netcore2.x though.

Also, have you updated Visual Studio lately? There have been some weird bugs that have been fixed by people updating Visual Studio (which updates MSBuild).

ashokj82 commented 3 years ago

Issue is with Convertusing. I have upgraded csvhelper with latest version and it doesnt support convertusing. And also GetField is not working.

public class CashManagementRecordMap : ClassMap { public CashManagementRecordMap() { Map(m => m.RevenueCenterNumber).ConvertUsing(o => Convert.ToInt32(o.GetField(1)));

        }
}
JoshClose commented 3 years ago

ConvertUsing was renamed to Convert.

ashokgovindaraj commented 2 years ago

Hi, while I upgrade to the latest version. I got this issue . At this line return (row as IReaderRow)?.Context.HeaderRecord

 Map(m => m.FacialImages).Convert(row =>
            {
                return (row as IReaderRow)?.Context.HeaderRecord
                    .Where(header => header.StartsWith("FacialImage"))
                    .Select(header =>
                    {
                        return new BioFacialImage()
                        {
                            FacialImage = row.Row.GetField<string>(header)
                        };
                    })
                    .ToList()
                    .Where(value => !string.IsNullOrWhiteSpace(value.FacialImage))
                    .ToList();
            });

Error is:

Cannot convert type 'CsvHelper.ConvertToStringArgs' to 'CsvHelper.IReaderRow' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion

I'm not sure how to convert this line (row as IReaderRow)?.Context.HeaderRecord

Kindly help me

JoshClose commented 2 years ago

The arguments to Convert changed. Just change to .Convert(args => then use args.row

 Map(m => m.FacialImages).Convert(args =>
            {
                return (args.Row as IReaderRow)?.Context.HeaderRecord
                    .Where(header => header.StartsWith("FacialImage"))
                    .Select(header =>
                    {
                        return new BioFacialImage()
                        {
                            FacialImage = row.Row.GetField<string>(header)
                        };
                    })
                    .ToList()
                    .Where(value => !string.IsNullOrWhiteSpace(value.FacialImage))
                    .ToList();
            });
jzabroski commented 1 year ago

See example below of a simple idiom that is probably so useful as to include in the official help docs, and one I rely upon extensively for ConvertFromString.

Map(m => m.LineNumber).Convert(x => x.Row.Context.Parser.RawRow);