jehugaleahsa / FlatFiles

Reads and writes CSV, fixed-length and other flat file formats with a focus on schema definition, configuration and speed.
The Unlicense
357 stars 64 forks source link

Flattening/anonymous type support #3

Closed programcsharp closed 10 years ago

programcsharp commented 10 years ago

I'm starting to implement FlatFiles in a couple of projects. Great stuff so far!

One thing I'm missing: Is there a way to get flattening and/or anonymous type support? That would only really work for writing, since flattening is a one way function, but it would save a lot of work creating DTO's when you actually are doing write only stuff.

What I'm looking for is something like (ignore the domain specific stuff -- this is an example of why I'd want flattening):

            var query = Session.Query<Disbursement>()
                .Where(x => x.Batch.Id == id && x.PaymentMethod == PaymentMethod.Check && x.CurrentPayment != null)
                .ToList()
                .Select(x => new
                {
                    x.CashAccount.AccountNumber,
                    x.CurrentPayment.Payment.CheckNumber,
                    x.CurrentPayment.Payment.Amount,
                    CheckDate = 
                });

            var mapper = FixedLengthTypeMapper.Define(query);

Note how I'm building an anonymous type from the IEnumerable.

This could be supported in a write only fashion by adding another overload to Define, like:

        public static IFixedLengthTypeMapper<TEntity> Define<TEntity>(IEnumerable<TEntity> data)
        {
            return new FixedLengthTypeMapper<TEntity>(() => Activator.CreateInstance<TEntity>());
        }

That would infer the type from the IEnumerable type. I tested this and it works, but obviously only for writing as anonymous types are read only.

Another option would be to allow deep references in the mapping definition, something like:

            mapper.Property(x => x.CashAccount.AccountNumber, 13);
            mapper.Property(x => x.CurrentPayment.Payment.CheckNumber, 10);
            mapper.Property(x => x.CurrentPayment.Payment.Amount, 10);
            mapper.Property(x => x.CurrentPayment.Payment.CheckDate.ToString("MMddyy"), 6);

I looked through the code, but that would require a much larger refactoring -- you'd have to:

jehugaleahsa commented 10 years ago

I am concerned this would lead to all kinds of awkward usage. I like the idea of configuring an anonymous type with type safety and Intellisense support. Let me think about this a little more.

jehugaleahsa commented 10 years ago

Within v0.1.7.0, you can do what you're suggesting. You will find a method under SeparatedValueTypeMapper and FixedLengthTypeMapper called DefineWriter. This returns the corresponding "writer" object, which supports the Property and GetSchema methods. Once you are done, you simple call Write which accepts a filename/stream and an options object.

I created two unit tests if you wanted to check them out.

Internally, the writers are just using the mappers. I just finessed the interface a little bit to protect it from misuse.

programcsharp commented 10 years ago

Ahh, cool!

I'll check it out.

On Wed, Jan 29, 2014 at 8:41 PM, Travis Parks notifications@github.comwrote:

Within v0.1.7.0, you can do what you're suggesting. You will find a method under SeparatedValueTypeMapper and FixedLengthTypeMapper called DefineWriter. This returns the corresponding "writer" object, which supports the Property and GetSchema methods. Once you are done, you simple call Write which accepts a filename/stream and an options object.

I created two unit tests if you wanted to check them out.

Internally, the writers are just using the mappers. I just finessed the interface a little bit to protect it from misuse.

Reply to this email directly or view it on GitHubhttps://github.com/jehugaleahsa/FlatFiles/issues/3#issuecomment-33657866 .