Dapper C#:无参数默认构造函数或一个匹配签名错误

发布于 2025-02-06 05:15:30 字数 2696 浏览 2 评论 0原文

我想获得给定表的分区列表。

public record Partition(string PartitionName, int OrdinalPosition);

public class MysqlService
{
    //...

    public IEnumerable<Partition> GetPartitions(string tableName)
    {
        using var conn = new MySqlConnection(_dbConnString);
        conn.Open();
        return conn.Query<Partition>(
            $"SELECT PARTITION_NAME, PARTITION_ORDINAL_POSITION " +
            $"FROM information_schema.partitions WHERE TABLE_NAME = '{tableName}';");
    }
}

但是我的代码给出了一个错误,例如

Unhandled exception. System.InvalidOperationException: A parameterless default constructor or one matching signature (System.String PARTITION_NAME, System.UInt64 PARTITION_ORDINAL_POSITION) is required for Services.Partition materialization
    at Dapper.SqlMapper.GenerateDeserializerFromMap(Type type, IDataReader reader, Int32 startBound, Int32 length, Boolean returnNullIfFirstMissing, ILGenerator il) in /_/Dapper/SqlMapper.cs:line 3297
    at Dapper.SqlMapper.GetTypeDeserializerImpl(Type type, IDataReader reader, Int32 startBound, Int32 length, Boolean returnNullIfFirstMissing) in /_/Dapper/SqlMapper.cs:line 3131
    at Dapper.SqlMapper.TypeDeserializerCache.GetReader(IDataReader reader, Int32 startBound, Int32 length, Boolean returnNullIfFirstMissing) in /_/Dapper/SqlMapper.TypeDeserializerCache.cs:line 151
    at Dapper.SqlMapper.TypeDeserializerCache.GetReader(Type type, IDataReader reader, Int32 startBound, Int32 length, Boolean returnNullIfFirstMissing) in /_/Dapper/SqlMapper.TypeDeserializerCache.cs:line 50
    at Dapper.SqlMapper.GetTypeDeserializer(Type type, IDataReader reader, Int32 startBound, Int32 length, Boolean returnNullIfFirstMissing) in /_/Dapper/SqlMapper.cs:line 3085
    at Dapper.SqlMapper.GetDeserializer(Type type, IDataReader reader, Int32 startBound, Int32 length, Boolean returnNullIfFirstMissing) in /_/Dapper/SqlMapper.cs:line 1835
    at Dapper.SqlMapper.QueryImpl[T](IDbConnection cnn, CommandDefinition command, Type effectiveType)+MoveNext() in /_/Dapper/SqlMapper.cs:line 1105
    at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
    at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
    at Dapper.SqlMapper.Query[T](IDbConnection cnn, String sql, Object param, IDbTransaction transaction, Boolean buffered, Nullable`1 commandTimeout, Nullable`1 commandType) in /_/Dapper/SqlMapper.cs:line 734
    ...

我该如何解决?

我尝试使用uint64而不是int用于ordinalPosition的类型,但是发生了相同的错误。

我的环境:

  • c#.net核心控制台应用程序(net6.0)
  • dapper 2.0.123
  • mysql 8.0

I would like to get list of partitions for a given table.

public record Partition(string PartitionName, int OrdinalPosition);

public class MysqlService
{
    //...

    public IEnumerable<Partition> GetPartitions(string tableName)
    {
        using var conn = new MySqlConnection(_dbConnString);
        conn.Open();
        return conn.Query<Partition>(
            
quot;SELECT PARTITION_NAME, PARTITION_ORDINAL_POSITION " +
            
quot;FROM information_schema.partitions WHERE TABLE_NAME = '{tableName}';");
    }
}

But my code gives an error like

Unhandled exception. System.InvalidOperationException: A parameterless default constructor or one matching signature (System.String PARTITION_NAME, System.UInt64 PARTITION_ORDINAL_POSITION) is required for Services.Partition materialization
    at Dapper.SqlMapper.GenerateDeserializerFromMap(Type type, IDataReader reader, Int32 startBound, Int32 length, Boolean returnNullIfFirstMissing, ILGenerator il) in /_/Dapper/SqlMapper.cs:line 3297
    at Dapper.SqlMapper.GetTypeDeserializerImpl(Type type, IDataReader reader, Int32 startBound, Int32 length, Boolean returnNullIfFirstMissing) in /_/Dapper/SqlMapper.cs:line 3131
    at Dapper.SqlMapper.TypeDeserializerCache.GetReader(IDataReader reader, Int32 startBound, Int32 length, Boolean returnNullIfFirstMissing) in /_/Dapper/SqlMapper.TypeDeserializerCache.cs:line 151
    at Dapper.SqlMapper.TypeDeserializerCache.GetReader(Type type, IDataReader reader, Int32 startBound, Int32 length, Boolean returnNullIfFirstMissing) in /_/Dapper/SqlMapper.TypeDeserializerCache.cs:line 50
    at Dapper.SqlMapper.GetTypeDeserializer(Type type, IDataReader reader, Int32 startBound, Int32 length, Boolean returnNullIfFirstMissing) in /_/Dapper/SqlMapper.cs:line 3085
    at Dapper.SqlMapper.GetDeserializer(Type type, IDataReader reader, Int32 startBound, Int32 length, Boolean returnNullIfFirstMissing) in /_/Dapper/SqlMapper.cs:line 1835
    at Dapper.SqlMapper.QueryImpl[T](IDbConnection cnn, CommandDefinition command, Type effectiveType)+MoveNext() in /_/Dapper/SqlMapper.cs:line 1105
    at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
    at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
    at Dapper.SqlMapper.Query[T](IDbConnection cnn, String sql, Object param, IDbTransaction transaction, Boolean buffered, Nullable`1 commandTimeout, Nullable`1 commandType) in /_/Dapper/SqlMapper.cs:line 734
    ...

How can I fix this?

I tried to use UInt64 instead of int for the type of OrdinalPosition, but the same error occured.

My Environment:

  • C# .NET Core Console Application (net6.0)
  • Dapper 2.0.123
  • MySQL 8.0

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一袭白衣梦中忆 2025-02-13 05:15:31

类型和名称必须匹配(或使用自定义映射)。
您可以使用别名在C#中具有“较好”的名称:

SELECT PARTITION_NAME AS PartitionName, PARTITION_ORDINAL_POSITION AS OrdinalPosition
FROM information_schema.partitions WHERE TABLE_NAME ...

公共记录partion(字符串partitionName,uint64 ordinalPosition)

您还应该处理您通过的潜在SQL注入问题
用wera-sare构建字符串。

Dapper使它变得足够容易:

public IEnumerable<Partition> GetPartitions(string tableName)
{
    using var conn = new MySqlConnection(_dbConnString);
    conn.Open();
    return conn.Query<Partition>(
        $"SELECT PARTITION_NAME AS PartitionName, PARTITION_ORDINAL_POSITION AS OrdinalPosition " +
        $"FROM information_schema.partitions WHERE TABLE_NAME = @tableName;", 
        new { tableName });
}

Types and names must match (or use a custom mapping).
You can use aliases to have "nicer" names in C#:

SELECT PARTITION_NAME AS PartitionName, PARTITION_ORDINAL_POSITION AS OrdinalPosition
FROM information_schema.partitions WHERE TABLE_NAME ...

public record Partion(string PartitionName, uint64 OrdinalPosition)

You should also deal with the potential SQL injection issue you have by
building a string with the WHERE-clause.

Dapper makes this easy enough:

public IEnumerable<Partition> GetPartitions(string tableName)
{
    using var conn = new MySqlConnection(_dbConnString);
    conn.Open();
    return conn.Query<Partition>(
        
quot;SELECT PARTITION_NAME AS PartitionName, PARTITION_ORDINAL_POSITION AS OrdinalPosition " +
        
quot;FROM information_schema.partitions WHERE TABLE_NAME = @tableName;", 
        new { tableName });
}
—━☆沉默づ 2025-02-13 05:15:31

同样的例外。您可以这样创建CTOR:

public Partition(){ }

Same Exception. You can create ctor like this:

public Partition(){ }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文