Skip to content
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

Constant doesn't work when there is no field in the CSV #1030

Closed
SuperSkippy opened this issue May 11, 2018 · 6 comments
Closed

Constant doesn't work when there is no field in the CSV #1030

SuperSkippy opened this issue May 11, 2018 · 6 comments
Labels

Comments

@SuperSkippy
Copy link

SuperSkippy commented May 11, 2018

I'm trying to write a map that always fills in one field in my output class with a constant value. However I can't, it only works when there is a field in the incoming csv file.

Here's a test for what I want to do. (an additional test in ConstantTests.cs)

        [TestMethod]
        public void ConstantNoFieldTest()
        {
            var rows = new Queue<string[]>();
            rows.Enqueue(new[] { "Id"});
            rows.Enqueue(new[] { "1"});
            rows.Enqueue(new[] { "2"});
            rows.Enqueue(null);
            var parser = new ParserMock(rows);

            var csv = new CsvReader(parser);
            csv.Configuration.RegisterClassMap<TestStringMap>();
            var records = csv.GetRecords<Test>().ToList();

            csv.Configuration.MissingFieldFound = null;

            Assert.AreEqual(1, records[0].Id);
            Assert.AreEqual("constant", records[0].Name);
            Assert.AreEqual(2, records[1].Id);
            Assert.AreEqual("constant", records[1].Name);
        }

(for reference, TestStringMap looks like:

private sealed class TestStringMap : ClassMap<Test>
		{
			public TestStringMap()
			{
				Map( m => m.Id );
				Map( m => m.Name ).Constant( "constant" );
			}
		}

)

@SuperSkippy
Copy link
Author

Why do I want to do this? I'm letting users define their own mappings in software then storing them in a database so they can use their own CSV file formats. Sometimes their file formats don't have all the fields. In that case the user wants to put in a constant, and that field won't be in the incoming CSV file.

@JoshClose
Copy link
Owner

I'll put this as a feature request. When writing you don't even have to specify a property and it works. I think this might have just been an oversight.

For now, you can do this.

Map(m => m.Name).ConvertUsing((IReaderRow row) => "the constant");

@marcrocny
Copy link
Contributor

marcrocny commented Jan 11, 2019

Interestingly, MemeberMap.Constant() does work if the underlying mapping is index-based. That is, with csv.Configuration.HasHeaderRecord = false, and the mapping is performed implicitly or explicitly by index.

A passing test (for Reading\ConstantTests.cs, as above):

[TestMethod]
public void ConstantNoFieldIndexMapTest()
{
    var rows = new Queue<string[]>();
    rows.Enqueue(new[] { "1" });
    rows.Enqueue(new[] { "2" });
    rows.Enqueue(null);
    var parser = new ParserMock(rows);

    var csv = new CsvReader(parser);
    csv.Configuration.RegisterClassMap<TestStringMap>(); // implicit index-map without Header
    csv.Configuration.HasHeaderRecord = false;
    var records = csv.GetRecords<Test>().ToList();

    Assert.AreEqual(1, records[0].Id);
    Assert.AreEqual("constant", records[0].Name);
    Assert.AreEqual(2, records[1].Id);
    Assert.AreEqual("constant", records[1].Name);
}

@gandhis1
Copy link

gandhis1 commented May 5, 2020

Came across this bug today as I tried to map a CSV to a POCO and add a hard-coded field. I could do it after the fact, but it just seemed cleaner to do it at the point of deserialization, where all of the other properties are set. Maybe I'll try to pick up where #1252 left off.

@Logopolis
Copy link

Logopolis commented Nov 13, 2020

I needed this feature today in order to add a Guid FileId to each record as it was being imported, to identify which import file generated the record. Dealing with lots of data so enumerating the records to fix them up is not desirable.

Used this workaround:
Map(m => m.FileId).ConvertUsing(row => myGuid);

@JoshClose
Copy link
Owner

Looks like this works in the current version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants