Dapper抛出“DynamicMethod的无效类型所有者”错误。

24

我正在尝试使用Dapper.net,并且我喜欢它。但是,当我尝试批量插入实体时,我遇到了以下错误:

DynamicMethod的类型所有者无效。

在System.Reflection.Emit.DynamicMethod.Init(String name,MethodAttributes attributes,CallingConventions callingConvention,Type returnType,Type [] signature,Type owner,Module m,Boolean skipVisibility,Boolean transparentMethod,StackCrawlMark& stackMark)中 在System.Reflection.Emit.DynamicMethod..ctor(String name,Type returnType,Type [] parameterTypes,Type owner,Boolean skipVisibility)中 在Dapper.SqlMapper.CreateParamInfoGenerator(Identity identity,Boolean checkForDuplicates,Boolean removeUnused,IList<code>1 literals)中,在D:\ Dev \ dapper-dot-net \ Dapper NET40 \ SqlMapper.cs:第3033行 在Dapper.SqlMapper.GetCacheInfo(Identity identity,Object exampleParameters,Boolean addToCache)中,在D:\ Dev \ dapper-dot-net \ Dapper NET40 \ SqlMapper.cs:第2138行 在Dapper.SqlMapper.<QueryImpl>d__61<T> .MoveNext()中,在D:\ Dev \ dapper-dot-net \ Dapper NET40 \ SqlMapper.cs:第1578行 在System.Collections.Generic.List<code>1 ..ctor(IEnumerable<code>1 collection)中 在System.Linq.Enumerable.ToList [TSource](IEnumerable<code>1 source)中 在Dapper.SqlMapper.Query [T](IDbConnection cnn,String sql,Object param,IDbTransaction transaction,Boolean buffered,Nullable<code>1 commandTimeout,Nullable<code>1 commandType)中,在D:\ Dev \ dapper-dot-net \ Dapper NET40 \ SqlMapper.cs:第1479行 在Dapper.SqlMapper.Query(IDbConnection cnn,String sql,Object param,IDbTransaction transaction,Boolean buffered,Nullable<code>1 commandTimeout,Nullable<code>1 commandType)中,在D:\ Dev \ dapper-dot-net \ Dapper NET40 \ SqlMapper.cs:第1418行 在NinjaEvaluation.Data.Database.DapperWrapper.<>c__DisplayClass4`1.b__3(SqlConnection sqlConnection,SqlTransaction transaction)中,在c:\ Projects \ InHouse \ ninjaevaluation \ NinjaEvaluation \ NinjaEvaluation.Data \ Database \ DapperWrapper.cs:第52行 在NinjaEvaluation.Data.Database.DapperWrapper.Invoke(Action`2 action)中,在c:\ Projects \ InHouse \ ninjaevaluation \ NinjaEvaluation \ NinjaEvaluation.Data \ Database \ DapperWrapper.cs:第68行

当我像这样运行查询时,即使在完全正常的情况下,也会发生这种情况:

        string sql = @" INSERT INTO XXX
                        (XXXId, AnotherId, ThirdId, Value, Comment)
                        VALUES
                        (@XXXId, @AnotherId, @ThirdId, @Value, @Comment)";

        var parameters = command
            .MyModels
            .Select(model => new
            {
                XXXId= model.XXXId,
                AnotherId= model.AnotherId,
                ThirdId= model.ThirdId,
                Value = model.Value,
                Comment = model.Comment
            })
            .ToArray();

...

sqlConnection.Query(sql, parameters, commandType: commandType, transaction: transaction)

我发现有人遇到了同样的问题,他们在这个SO线程中讨论。但是那里的问题似乎是 .NET 版本(3.5),而我正在使用 .NET 4.5,我无法找出问题所在。你有什么建议吗?

我想知道 - 这是受限信任环境吗?还是普通的.NET没有什么特别的? - Marc Gravell
常规本地环境。没有任何限制。 - Maffelu
2个回答

42

在使用接口而不是类时,我遇到了这个错误:

Query<MyObject> 可以工作,而 Query<IMyObject> 则无法正常工作。


这也是我遇到的问题。 - scottheckel
6
我跟你遇到了相同的问题,当我使用接口而不是类时遇到了这个错误:Query<MyObject>可以工作,而Query<IMyObject>则不行。你应该确保在执行命令时,返回值使用的是类类型而不是接口。 - Ammar Al-Habib
使用接口是罪魁祸首,请使用具体类。如果传递接口,Dapper 将无法工作。 - Prateek Kumar Dalbehera
切换回到该类也解决了我的问题。 - user5081712
同样的问题出现在这里。使用接口是导致我的问题的原因。 - RosieC
我的问题基本上是一样的,但在尝试检索对象列表时,我错误地写成了 Query<IEnumerable<MyObject>> 而不是 Query<MyObject> - Lukas

17

由于该场景使用 Query[<T>] 并不期望参数的数组/序列,因此它失败了。 Execute被调用时期望这种情况,并自动展开数据,每个项执行一次SQL语句 - 但是对于 Query [<T>] 不是这种情况,因此它试图创建绑定到数组(在您的情况下)的动态方法,这是不允许的。 代码可能应该更早地检测到这一点,并且只是说“不行,这是不允许的”。

可能想将.ToArray()更改为.Single()

在下一个版本中,这将更清晰;以下内容已通过:

    public void SO30435185_InvalidTypeOwner()
    {
        try {
            // not shown for brevity: something very similar to your code
            Assert.Fail();
        } catch(InvalidOperationException ex)
        {
            ex.Message.IsEqualTo("An enumerable sequence of parameters (arrays, lists, etc) is not allowed in this context");
        }
    }

我应该使用Execute :) - Maffelu
1
@Maffelu 哈哈,就是那样 ;p - Marc Gravell
这是Dapper的缺陷,还是使用参数序列查询在逻辑上没有意义?这个问题关注的是选择插入行的ID,但在当前版本的Dapper中不可能实现。这个问题暗示它曾经可以工作-第一个片段-或者他们的错误与此有关吗?对我来说,如果Execute可以处理参数序列,那么Query也应该能够处理。我能想到的最好的解决方法涉及4个单独的查询,这并不理想。 - Rob
1
@Rob 嗯,循环出现的位置对实际操作并没有太大影响;是的,我们可以让“查询”与序列一起工作,并基本上连接结果,但这会更清晰吗? - Marc Gravell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接