Skip to content

Dapper isn't mapping correctly #326

Description

@ianlee74

We're about ready to rip Dapper out of everything... Everything worked great when we did the initial development but over the past year we have had numerous times when for no apparent reason it just starts incorrectly mapping SQL columns to the POCO properties. It seems to most often be when there is an "Id" column and another column that contains the word "Id" (i.e. "SurveyId"). It also seems to be related to the query having a JOIN despite that no columns from the join are SELECTed. I really hope someone can help us figure out what we're doing wrong because I'd hate to stop using Dapper but this unpredictable behavior is unacceptable. Here's the current example...

[DataContract]publicclassClientSurvey{[DataMember(EmitDefaultValue=false)]publicintId{get;set;}[DataMember]publicintClientId{get;set;}[DataMember(EmitDefaultValue=false)]publicintSurveyId{get;set;}[DataMember]publicstringName{get;set;}[DataMember]publicDateTimeStartDate{get;set;}[DataMember]publicDateTime?EndDate{get;set;}[DataMember]publicboolIsPatientDefault{get;set;}[DataMember]publicboolIsLocked{get;set;}[DataMember]publicSurveySurvey{get;set;}[DataMember]publicstringIntroHtml{get;set;}[DataMember]publicstringOutroHtml{get;set;}[DataMember]publicintMaxResponses{get;set;}}

...

publicasyncTask<ClientSurvey>GetDefaultAsync(intclientId){// NOTE: This was actually "select cs.*" but has been spelled out for better understanding and to see if it would help with the mapping. It did not.conststringsql=@"select cs.[Id], cs.[ClientId], cs.[SurveyId], cs.[Name], cs.[StartDate], cs.[EndDate], cs.[IsPatientDefault], cs.[ClientSurveyBundleId], cs.[IsLocked], cs.[IntroHtml], cs.[OutroHtml], cs.[MaxResponses], cs.[Description] from dbo.ClientSurveys cs inner join dbo.Surveys s on s.Id = cs.SurveyId where cs.ClientId = @clientId and cs.IsPatientDefault = 1 and isnull(cs.EndDate, '9999-1-1') > getdate()  and isnull(cs.StartDate, '2000-1-1') < getdate()  and s.IsActive = 1;";using(varcnn=awaitOpenConnectionAsync()){varsurveys=(awaitcnn.QueryAsync<ClientSurvey>(sql,new{ClientId=clientId})).ToList();if(!surveys.Any()){returnnull;}if(surveys.Count()>1){thrownewException("Multiple default surveys for client "+clientId);}varclientSurvey=surveys.First();clientSurvey.Survey=awaitSurveysData.Instance.GetAsync(clientSurvey.SurveyId,clientSurvey.ClientId);clientSurvey.SurveyId=0;// Clear this so it doesn't serialize out and duplicate the data.awaitReplaceVariables(clientSurvey);returnclientSurvey;}}

If this SQL is called in SSMS, I get back (among other things...): Id = 3, SurveyId = 2

However, if I call the function above then it assigns: clientSurvey.Id = 2, clientSurvey.SurveyId = 2
(note that there is not a record in the database where ClientSurvey.Id = 2)

So far we've managed to do weird things like changing or removing JOINs in exchange for less desirable queries just to force Dapper to get the mapping correct but this now seems to be an almost daily problem. Is anyone else experiencing this?

Our databases are Azure Database (v12) and our code is running in an Azure Website running .NET 4.5.2.

Thanks for any help you can offer. This is an urgent problem for us.

Ian

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions