1

最近几天我一直在重构一个项目。该项目使用 Dapper 和 SqlMapper 功能将 Sql 查询的结果映射到对象上。作为我重构的一部分,我将一些对象移动到一个单独的程序集中,这就是事情变得有点不对劲的地方。

    public async Task<IEnumerable<HL7Control>> GetHl7ControlRecords()
    {
        _log.Info("Obtaining a list of required transfer service agents.");

        var agentList = StatementBuilder.BuildDapperGetAllHl7ControlRecords();

        return await SqlMapper.QueryAsync<HL7Control>(_db, agentList.Sql,agentList.Param);
    }

这不断抛出一个 RuntimeBinder 异常,说 'QueryAsync<>' 不是 SqlMapper 的成员。这是已经运行了六个月以上的代码。

我终于找到了问题所在,我很感激其他人的一些想法。“解决方案”是用浏览引用替换对包含“HL7Control”的程序集的项目引用(即;在项目文件中<Project Reference Include...><Reference Include...>

该解决方案由 vs2015 构建,并以 .NET4.6 为目标,但以 .NET4.0 为目标的新程序集除外。

欢迎任何想法,因为当我不理解“修复”时我会不高兴。

谢谢。

更新 1. 更多信息。我忽略了 agentList 不仅名字不好,而且实际上是一个类:

public class DapperStatement
{
    public string Sql { get;  }

    public dynamic Param { get; }

    public DapperStatement(string sql, dynamic param)
    {
        Sql = sql;
        Param = param;
    }
}

正是因为 Param 是动态的,才涉及到 RuntimeBinder。现在我知道动态不会跨越程序集边界,这是我在重构期间必须解决的其他问题。但是在这种情况下,尽管 DapperStatement在不同的程序集中定义的,但对象实例并未穿过程序集边界。DapperStatement 总是在另一个程序集中使用它。

另请注意, SqlMapper.Query<> 始终有效,因此显然异步是其中的一个因素。

我还一夜之间重新启动了我的机器并从头开始重建,但问题仍然存在。

哦,将新程序集更改为 .NET4.6 不会改变任何东西(除了破坏正在为其开发的外部客户端项目,哈哈)。

更新 2. 问题似乎特定于 Dapper。进一步解释需要更多细节,所以这里是:最初我们有一个包含多个项目的解决方案。其中一个项目(项目 A)使用 Dapper 来访问和操作一些 SQL 表。然后其他几个项目依赖于此。

同时,另一个外部项目需要访问相同的表,但使用的是 DevExpress XPO。所以我这周一直在做的是移动一些东西,以便 XPO 不再访问这些表。原始的 Dapper 代码做了更多的工作,所以我们决定只删除外部项目需要的东西。这给我们留下了两个使用 Dapper 来操作 SQL 数据库的程序集。看起来我看到的问题是,在那种情况下,有一个项目参考而不是浏览参考会把事情搞砸。

今天早上,我从新项目中删除了 Dapper 引用,突然旧代码再次与浏览器引用一起工作(只要避免我不得不破解的调用)。

4

3 回答 3

2

在 VS 2017 中遇到 Dapper 的这个问题时,我必须执行以下操作:

  • 使用 Dapper 的项目下右键单击“管理 NuGet 包”,选择 Dapper,然后在屏幕的安装/卸载侧,展开选项并将“安装和更新选项 - 依赖行为”更改为“最高”。这使最新版本的 Dapper.dll 出现在项目的 bin 文件夹中(而不是 2012 年的版本)。
  • 在顶级项目的App.config中,包括包含 Dapper 依赖项的库,删除以下部分(这篇文章给了我提示 - https://blogs.msdn.microsoft.com/bclteam/p/asynctargetingpackkb/问题 #6 )

    <dependentAssembly>
        <assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.1.1.0" newVersion="4.1.1.0" />
    </dependentAssembly>
    

通过这两项更改,我的应用程序开始与面向 .Net Framework v4.7.1 的自定义程序集正常工作

于 2018-05-03T16:51:07.497 回答
1

听起来你已经从 1 个 sln 变成了 2 个。当 NuGet 参与时,我在处理 2 个 sln 文件时遇到了一些麻烦,包括相同的项目。HintPath 是相对于项目的,并且可能会根据文件夹结构变得混乱。

如果:

源 -app1 --sln1 ---proj1WithNugetDep -app2 --sln2 ---proj2WithSameNugetDep

然后:

我发现用“$(SolutionFolder)/packages”替换通常适用于这种情况。

于 2017-01-11T12:23:20.583 回答
0

我现在很确定这是由于框架不匹配造成的。当使用项目引用时,复制到可执行文件夹中的 Dapper 程序集用于 .NET4,而 .NET4.6 代码显然对此感到窒息。当使用浏览引用时,会复制 .NET4.6 Dapper 程序集,一切都很好。

于 2017-01-13T08:26:55.593 回答