2017-03-03 106 views
0

我试图将文件名列表插入到简单的Sql Server表中。尝试将.NET字符串[]映射到FastMember对象,但它出错/未映射

我试图利用SqlBulkCopy和@markgravell's FastMember库,正如其他SO答案所建议的。

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 

所以我觉得这是一个映射问题,要么: - FastMember无法映射到一些内部后盾收集 - 该FastMember后盾集合并不具有相同的名称作为数据库列,因此它可以地图。

谁能帮助吗?

+0

您可以编写自己的IDataReader实现。 SqlBulkCopy只调用阅读器上的GetValue,Read和FieldCount实现,因此编写自定义阅读器相对容易。只是一个想法。 – TnTinMn

回答

1

我从来没有使用过这个库,但在审查GitHub源代码之前,它需要一个属性来从源查询。现在在一个字符串中没有一个属性value所有你必须使用的是Length属性。使用Length。现在,这可能是FastMember库的一个问题,它会创建一个CallSite访问器函数来捕获目标对象的属性。

Source here

现在我有一出戏,并不能获得访问,将工作的任何财产。乍一看,他们是Chars财产正在TypeAccessor结果返回,但这似乎不工作。

我的建议并不是真正解决问题的方法,而是解决问题的方法。如果你创建了一个具有字符串属性的类型,那么你可以有效地解决这个问题。

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) 
      { 

      } 
     } 
    } 
} 

现在,当我们产生一种新型的具有value一个属性,它是每一个文件名,这将工作。现在执行应该按预期工作。 (请注意,try..catch...仅用于测试)。

+0

我很害怕这个建议的答案,因为那时我会拥有两份数据副本。当然,我们不是在谈论一个bazillion(源)字符串......但这是关键。这就是为什么我在OP中避免提及这一点。嗯.......无赖。但是,是的......我在回答这个问题的时候也是这样想的。 –

+0

@ Pure.Krome抱歉无法找到另一种方法来破解它,而无需实际更改并重新编译FastMember的源代码。我尝试了访问方法的方法(即在一个字符串上调用'ToString()'),但它只锁定了属性。 – Nico

+0

没问题。 :)尽管我非常感谢你的时间! –