Dapper - <>f__AnonymousType.....类型的成员不能用作参数值

Posted

技术标签:

【中文标题】Dapper - <>f__AnonymousType.....类型的成员不能用作参数值【英文标题】:Dapper - The member of type <>f__AnonymousType.....cannot be used as a parameter value 【发布时间】:2021-06-23 12:31:26 【问题描述】:

我正在尝试执行一个返回返回值的存储过程。

但我收到错误消息:

2021-06-23 14:02:37.844 +02:00 [ERR] 类型的成员 f__AnonymousType0`3[[System.Int32,mscorlib,版本=4.0.0.0, 文化=中性,PublicKeyToken=b77a5c561934e089],[System.String, mscorlib,版本=4.0.0.0,文化=中性, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, 版本=4.0.0.0,文化=中性,PublicKeyToken=b77a5c561934e089]] 不能作为参数值

List<Person2> persons = new List<Person2>()
            
                new Person2()  Id = 22, FirstName = "Calvin", LastName = "Kattar" ,
                new Person2()  Id = 23, FirstName = "Edson", LastName = "Barboza" 
            ;
            
            using (IDbConnection connection = new OracleConnection(GetConnectionString()))
            
                try
                
                    var personProjections = persons.Select(x => new   id = x.Id, first_name = x.FirstName, last_name = x.LastName, out_message = x.OutMessage);

                    var results = connection.Query<Person2>("kwc_test_person_procedure2",
                    new  personProjections ,
                    commandType: CommandType.StoredProcedure
                    );                   
                
                catch (Exception ex)
                
                    Log.Error(ex.Message);
                    Log.Error(ex.StackTrace);
                    throw;
                
            

我的类型是:

public class Person
    
        public int Id  get; set; 

        public string FirstName  get; set; 

        public string LastName  get; set; 
    

public class Person2 : Person 
    
        public string OutMessage  get; set; 
    

还有存储过程:

create or replace procedure kwc_test_person_procedure2(
id in number,
first_name in varchar2,
last_name in varchar2,
out_message out varchar2
) is

begin
  insert into kwc_test_person(id, first_name, last_name) values (id, upper(first_name), upper(last_name));
  out_message := 'The person-ID ' || id || ' has been inserted to database on ' || sysdate;

End kwc_test_person_procedure2;

我在这里做错了什么?

提前致谢!

【问题讨论】:

对每个项目执行一个过程会很慢。您可能需要一个表参数(不确定您如何在 Oracle 中执行此操作,我认为您需要一个 UDT),然后通过 .AsTableValuedParameter 在 Dapper 中传递它。 @Charlieface,谢谢你的建议。我打算使用并行执行。而且程序会在夜间运行,所以速度慢应该不是问题。 【参考方案1】:

Query(...) 的参数param 类型错误。它必须是一个平面对象,该对象具有您正在调用的过程的每个参数的属性或字段。像这样的东西会起作用:

connection.Query("kwc_test_person_procedure2",
new  id = 1, first_name = "...", ...,
commandType: CommandType.StoredProcedure

由于您想为多人实例调用该过程,您的代码应如下所示:

 foreach(var personProjection in persons.Select(x => new   id = x.Id, first_name = x.FirstName, last_name = x.LastName, out_message = x.OutMessage)
 
                connection.Query("kwc_test_person_procedure2",
                personProjection,
                commandType: CommandType.StoredProcedure);     
 
         

至于过程的返回值,我不确定它在 Oracle 中是否是这样工作的;在 MSSQL 中,返回值将是过程中最后一次选择的结果。看起来在 oracle 中可能是一样的,请参阅this。

【讨论】:

感谢 Stefan 的回复。这行得通。我还最终在 ForEach 循环中使用了 DynamicParameters,并且能够通过指定方向来获取返回值:ParameterDirection.Output。

以上是关于Dapper - <>f__AnonymousType.....类型的成员不能用作参数值的主要内容,如果未能解决你的问题,请参考以下文章

带参数的 Dapper Postgres 存储过程

Codeforces_734_F

_TypeError(类型 '_InternalLinkedHashMap<String, dynamic>' 不是类型 'Iterable<dynamic>' 的子类型) F

Codeforces_731_F

面向对象编程

[Haoi2016]放棋子