ここ数日、プロジェクトのリファクタリングに費やしてきました。このプロジェクトでは、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);
}
これにより、'QueryAsync<>' が SqlMapper のメンバーではないことを示す RuntimeBinder 例外がスローされ続けました。これは、6 か月以上問題なく使用されているコードです。
私はついに問題を突き止めました。他の人からの考えに感謝します。「解決策」は、「HL7Control」を含むアセンブリへのプロジェクト参照をブラウズ参照に置き換えることです(つまり、プロジェクトファイルに<Project Reference Include...>
なります。<Reference Include...>
このソリューションは vs2015 によって構築されており、.NET4.0 を対象とする新しいアセンブリを除いて、.NET4.6 を対象としています。
「修正」を理解できないと嬉しくないので、どんな考えでも大歓迎です。
ありがとう。
更新 1. いくつかの詳細情報。agentList は名前が悪いだけでなく、実際にはクラスであることを忘れていました。
public class DapperStatement
{
public string Sql { get; }
public dynamic Param { get; }
public DapperStatement(string sql, dynamic param)
{
Sql = sql;
Param = param;
}
}
そして、RuntimeBinder が関与するのは、Param が動的であるためです。これで、動的はアセンブリの境界を越えないことがわかりました。これは、このリファクタリング中に対処しなければならなかった別のことです。ただし、この場合、DapperStatementは別のアセンブリで定義されていますが、オブジェクト インスタンスはアセンブリの境界を越えていません。そして、DapperStatement は常に、それが使用されている別のアセンブリにありました。
また、 SqlMapper.Query<> は常に機能するため、明らかに非同期であることがこれの要因であることに注意してください。
また、マシンを一晩再起動し、最初から再構築しましたが、問題は残ります。
ああ、新しいアセンブリを .NET4.6 に変更しても何も変わりません (それが開発されている外部クライアント プロジェクトを壊す以外は、笑)。
更新 2。 問題は Dapper に固有のようです。さらに説明するには、もう少し詳しく説明する必要があります。最初は、複数のプロジェクトで 1 つのソリューションを使用していました。これらのプロジェクトの 1 つ (プロジェクト A) では、Dapper を使用していくつかの SQL テーブルにアクセスして操作しました。その後、他のいくつかのプロジェクトがそれに依存していました。
その間、別の外部プロジェクトが同じテーブルにアクセスする必要がありましたが、DevExpress XPO を使用していました。そこで、私が今週行ったことは、テーブルが XPO によってアクセスされないようにすることです。元の Dapper コードははるかに多くのテーブル作業を行うため、外部プロジェクトが必要とするものだけをハイブすることにしました。これで、Dapper を使用して SQL データベースを操作する 2 つのアセンブリが残ります。私が見ている問題は、そのシナリオでは、ブラウズ参照ではなくプロジェクト参照を使用すると、問題が発生することです。
今朝、新しいプロジェクトから Dapper リファレンスを削除したところ、突然古いコードがブラウザー リファレンスで再び機能するようになりました (ハッキングしなければならなかった呼び出しを避ける限り)。