简体   繁体   English

C#Dapper和FastMember - 不支持指定的方法

[英]C# Dapper and FastMember - Specified method not supported

I have a C# .NET Core 2.0 Web API project (implemented as a microservice). 我有一个C#.NET Core 2.0 Web API项目(作为微服务实现)。

I am using NuGet Packages "Dapper" and "FastMember" (latest versions) in my repository layer to try to convert an IEnumerable<T> to a DataTable via the ObjectReader that FastMember provides, so that I can take advantage of Dapper's built-in ICustomQueryParameter SqlMapper to pass a table-valued parameter to a stored procedure that I am using in SQL Server. 我在我的存储库层中使用NuGet Packages“Dapper”和“FastMember”(最新版本)尝试通过FastMember提供的ObjectReader将IEnumerable<T>转换为DataTable,以便我可以利用Dapper的内置ICustomQueryParameter SqlMapper将表值参数传递给我在SQL Server中使用的存储过程。

When I execute and debug my code, it throws an exception on the line where the FastMember ObjectReader attempts to be loaded into a DataTable: table.Load(reader); 当我执行并调试我的代码时,它会在FastMember ObjectReader尝试加载到DataTable的行中引发异常: table.Load(reader); .

Here is my Dapper wrapper/extension method that contains the problematic line: 这是我的Dapper包装器/扩展方法,其中包含有问题的行:

public static class DapperExtensions
{
    public static SqlMapper.ICustomQueryParameter AsTvp<T>(this 
    IEnumerable<T> enumerable, string typeName) where T : class
        {
            var table = new DataTable();
            var members = typeof(T).GetProperties().Select(p => p.Name).ToArray();
            using (var reader = ObjectReader.Create(enumerable.ToList(), members))
            {
                table.Load(reader);
            }
            return table.AsTableValuedParameter(typeName);
        }
}

Here is my Dapper call that uses the above extension method: 这是我使用上述扩展方法的Dapper调用:

using (var dbConnection = new SqlConnection(_connectionString))
{
    var result = dbConnection.Query("[PurchaseOrders].[Add] @tvpNewPurchaseOrderItems, @StartDate", new
    {
        tvpNewPurchaseOrderItems = purchaseOrderCreationRequest.PurchaseOrderItems.AsTvp("NewPurchaseOrderType"),
    StartDate = purchaseOrderCreationRequest.StartDate
    });
}

And here is the stack trace from my C# exception that was thrown: 这是我抛出的C#异常的堆栈跟踪:

at System.Data.Common.DbDataReader.GetSchemaTable()
at System.Data.ProviderBase.SchemaMapping..ctor(DataAdapter adapter, DataSet dataset, DataTable datatable, DataReaderContainer dataReader, Boolean keyInfo, SchemaType schemaType, String sourceTableName, Boolean gettingData, DataColumn parentChapterColumn, Object parentChapterValue)
at System.Data.Common.DataAdapter.FillMappingInternal(DataSet dataset, DataTable datatable, String srcTable, DataReaderContainer dataReader, Int32 schemaCount, DataColumn parentChapterColumn, Object parentChapterValue)
at System.Data.Common.DataAdapter.FillMapping(DataSet dataset, DataTable datatable, String srcTable, DataReaderContainer dataReader, Int32 schemaCount, DataColumn parentChapterColumn, Object parentChapterValue)
at System.Data.Common.DataAdapter.FillFromReader(DataSet dataset, DataTable datatable, String srcTable, DataReaderContainer dataReader, Int32 startRecord, Int32 maxRecords, DataColumn parentChapterColumn, Object parentChapterValue)
at System.Data.Common.DataAdapter.Fill(DataTable[] dataTables, IDataReader dataReader, Int32 startRecord, Int32 maxRecords)
at System.Data.DataTable.Load(IDataReader reader, LoadOption loadOption, FillErrorEventHandler errorHandler)
at System.Data.DataTable.Load(IDataReader reader)
at PurchaseOrderCreationRepositories.Extensions.DapperExtensions.AsTvp[T](IEnumerable`1 enumerable, String typeName) in C:\Projects-Git\Enterprise\PurchaseOrderCreationService\PurchaseOrderCreationRepositories\Extensions\DapperExtensions.cs:line 16
at PurchaseOrderCreationRepositories.PurchaseOrderRepository.Add(IPurchaseOrderCreationRequest purchaseOrderCreationRequest) in C:\Projects-Git\Enterprise\PurchaseOrderCreationService\PurchaseOrderCreationRepositories\PurchaseOrderRepository.cs:line 22
at PurchaseOrderCreationServices.PurchaseOrderService.Add(IPurchaseOrderCreationRequest purchaseOrderCreationRequest) in C:\Projects-Git\Enterprise\PurchaseOrderCreationService\PurchaseOrderCreationServices\PurchaseOrderService.cs:line 18
at PurchaseOrderCreationServiceApi.Controllers.PurchaseOrderCreationController.Add(PurchaseOrderCreationRequest purchaseOrderCreationRequest) in C:\Projects-Git\Enterprise\PurchaseOrderCreationService\PurchaseOrderCreationServiceApi\Controllers\PurchaseOrderCreationController.cs:line 25

Exception message was: Specified method is not supported. 异常消息是: Specified method is not supported.

Can anybody help me with this error?? 任何人都可以帮我解决这个错误吗? It doesn't make sense to me that .NET Core 2.0 wouldn't support this method. 对我来说,.NET Core 2.0不支持这种方法是没有意义的。 And I have used FastMember in other .NET Core 2.0 apps successfully with SqlBulkCopy. 我已经使用SqlBulkCopy在其他.NET Core 2.0应用程序中成功使用了FastMember。 But this is the first time that I've tried using it with Dapper. 但这是我第一次尝试将它与Dapper一起使用。

Any help is much appreciated! 任何帮助深表感谢! Thanks in advance. 提前致谢。

This is FastMember's fault. 这是FastMember的错。 Basically, for a very long time , the .NET Core API for ADO.NET didn't provide this API at all , which meant that any code targeting it could not implement it . 基本上, 很长一段时间 ,对ADO.NET的.NET核心API没有提供这个API的所有,这意味着任何代码针对它无法实现它

This has now been rectified in newer versions of .NET Core, but I have failed to revisit FastMember to add back in the API. 现在已经在较新版本的.NET Core中对此进行了修正,但我没有重新访问FastMember以在API中添加。 I will try to do this tonight and get a new deployment out ASAP. 今晚我会尽力做到这一点并尽快获得新的部署。

Essentially, FastMember has: 基本上,FastMember有:

#if !COREFX
    public override DataTable GetSchemaTable()
    {...}
#endif

because: it couldn't override a method that didn't exist on the base class at the time. 因为:它无法override当时基类上不存在的方法。


This has been fixed in v1.2.0 when targeting suitable target platforms including netstandard2.0 在针对包括netstandard2.0在内的合适目标平台时,已在v1.2.0中修复此netstandard2.0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM