Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'Dapper.SqlMapper' does not contain a definition for 'QueryAsync' #675

Closed
AndrueCope opened this issue Jan 10, 2017 · 13 comments
Closed

'Dapper.SqlMapper' does not contain a definition for 'QueryAsync' #675

AndrueCope opened this issue Jan 10, 2017 · 13 comments

Comments

@AndrueCope
Copy link

AndrueCope commented Jan 10, 2017

We have a core assembly that has been working fine for several months. I've done some refactoring and now we can only use SqlMapper.QueryAsync<>() when the library is called from our unit test projects. When our applications call into it they get the above exception. SqlMapper.Query<> still works.

Call stack:

   at CallSite.Target(Closure , CallSite , Type , IDbConnection , String , Object )
   at System.Dynamic.UpdateDelegates.UpdateAndExecute4[T0,T1,T2,T3,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2, T3 arg3)
   at Lexacom.Byzantium.Core.SqlServer.SqlHelper.<GetHl7ControlRecords>d__28.MoveNext() in C:\Work\lexacom\Lexacom.Byzantium.Core\SqlServer\SqlHelper.cs:line 333
@NickCraver
Copy link
Member

Can you paste the code calling this?

@AndrueCope
Copy link
Author

AndrueCope commented Jan 10, 2017

namespace Lexacom.Byzantium.Core.SqlServer // All these are in the same assembly.

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);
}
...
public DapperStatement BuildDapperGetAllHl7ControlRecords()
{
    return new DapperStatement("SELECT * FROM HL7Control", null);
}
...
public class DapperStatement
{
    public string Sql { get;  }

    public dynamic Param { get; }

    public DapperStatement(string sql, dynamic param)
    {
        Sql = sql;
        Param = param;
    }
}
...
namespace Lexacom.Byzantium.Client.Lexacom3.Models // This is now in a separate assembly.

public class HL7Control
{
    public Guid Id { get; set; }
    public string AgentName { get; set; }
    public string ServiceFailureMessage { get; set; }
    public bool Enabled { get; set; }
}

@AndrueCope
Copy link
Author

AndrueCope commented Jan 10, 2017

A bit more info. I changed the working Query<>() to async and that breaks now:

private bool TableExists(string tableName)
{
    var tableExists = StatementBuilder.CheckIfTableExists(tableName);

    var result=SqlMapper.QueryAsync<string>(_db, tableExists.Sql, tableExists.Param).Result;

    return result.Count == 1;
}

Also if I get rid of the dynamic the code fails when it tries to call the method complaining that:

Additional information: Method not found: 
'System.Threading.Tasks.Task`1<System.Collections.Generic.IEnumerable`1<!!0>> Dapper.SqlMapper.QueryAsync(System.Data.IDbConnection, System.String, System.Object, System.Data.IDbTransaction, System.Nullable`1<Int32>, System.Nullable`1<System.Data.CommandType>)'.

So somehow it seems that QueryAsync<> has just 'gone'.

@NickCraver
Copy link
Member

It sounds like your library calling Dapper is compiled against a very old version of Dapper, which pre-dates these methods. Or is another library is causing an older version of Dapper to actually be loaded. Please check your output directory and look at the version of Dapper.dll.

@AndrueCope
Copy link
Author

AndrueCope commented Jan 10, 2017

Ooohhkay! I know the cause.

It's because HL7Control was moved into a different namespace when I moved it into another assembly.

It used to be: Lexacom.Byzantium.Core.SqlServer.SqlStatements.HL7Control
but became: Lexacom.Byzantium.Client.Lexacom3.ClientModels.

If I change the namespace back (but keep it in a separate assembly) QueryAsync<>() works again. I'm not sure how it worked for our unit tests anyway but..meh.

@AndrueCope
Copy link
Author

So..it doesn't have to be in the same namespace as the code calling it but does have to be in the namespace 'path' (ie; has the same parent namespace).

@AndrueCope
Copy link
Author

Darn. That worked for one project but not for another (in the same solution). So the saga continues :-/

@AndrueCope
Copy link
Author

AndrueCope commented Jan 10, 2017

My apologies for the spam. I have finally found the answer. It's nothing to do with the namespaces. It's to do with the project files and how they reference the new assembly. If they use 'Project Reference Include...' Dapper will fail. But if they use 'Reference Include...' they are fine. Something smells here :-/

@AndrueCope
Copy link
Author

I have more information. The problem is caused by the fact we have two projects in the same solution both referencing Dapper. As explained here I've been creating a sub assembly that contains Dapper code that is common to our main project and to an external project.

That results in 'Class library A' - 80% of our Dapper using code and a dependency of several EXEs.
'Class library B - 10% of our Dapper using code and a dependency of an external EXE and of 'Class library A'.

If I hack 'Class library B' so that it doesn't reference Dapper (by commenting out the functionality) the problem goes away.

@NickCraver
Copy link
Member

We're going to address this properly with Strong-Naming in v2. Unfortunately you're in a special kind of package/reference hell that Strong-Naming was meant to address. Adding to the v2 list.

@NickCraver
Copy link
Member

Closing this out since the remaining issue is the strong naming combination, coming in #688.

@lharland
Copy link

Check if a SqlMapper.cs file exist in the project directory somewhere embedded in a subfolder

@mbenitez159
Copy link

mbenitez159 commented Nov 19, 2020

Thank so much @AndrueCope, I was stuck in the same problem , I just remove the Dapper library from My API and just left dapper insolate in business class library.
It works great

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants