Trying to map a .NET string[] to a FastMember object but it's erroring/not mapping

.net c# fastmember sqlbulkcopy sql-server

Question

I'm trying to insert a list of file names into a simple Sql Server table.

I'm trying to leverage SqlBulkCopy and @markgravell's FastMember library, as suggested by other SO answers.

public async Task AddFileNamesAsync(string[] fileNames)
{
    fileNames.ShouldNotBeNull();

    using (var bulkCopy = new SqlBulkCopy(ConnectionString))
    {
        using (var reader = ObjectReader.Create(fileNames))
        {
            bulkCopy.DestinationTableName = "FileNames";
            bulkCopy.ColumnMappings.Add("value", "FileName");
            await bulkCopy.WriteToServerAsync(reader)
                          .ConfigureAwait(false);
        }
    }
}

CREATE TABLE [dbo].[FileNames](
[FileNameId] [int] IDENTITY(1,1) NOT NULL,
[FileName] [varchar](500) NOT NULL

So i feel like it's a mapping issue either with: - FastMember not able to map to some internal backing collection - The FastMember backing collection doesn't have the same name as the DB column so it can't map.

Can anyone help, please?

Accepted Answer

I have never used this Library before however reviewing the GitHub source code it it requires a property to query from the source. Now on a string there isn't a property value really all you have to use is the Length property. Using Length. Now this may be an issue with the FastMember library, where it creates a CallSite accessor function to capture the Property from the target object.

Source here

Now I have had a play and cannot get access to any property that will work. At first glance their is a Chars property being returned in the TypeAccessor results but this does not appear to work.

My suggestion is not really an answer to the question but a way to make it work. If you created a type that had a Property of the string then you could effectively get around this.

public async Task AddFileNamesAsync(string[] fileNames)
{
    fileNames.ShouldNotBeNull();

    var list = fileNames.Select(f => new { value = f });

    using (var bulkCopy = new SqlBulkCopy(ConnectionString))
    {
        using (var reader = ObjectReader.Create(list))
        {
            bulkCopy.DestinationTableName = "FileNames";
            bulkCopy.ColumnMappings.Add("value", "FileName");

            try
            {
                await bulkCopy.WriteToServerAsync(reader)
                                .ConfigureAwait(false);

            }
            catch(Exception ex)
            {

            }
        }
    }
}

Now this will work as we generated a new type with a property of value which is each file name. Now the execution should work as expected. (Note the try..catch... was just for testing).



Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why