Search code examples
c#.net-coredependency-injectiondapper

Objects return as Defaults when using Dapper with a Constructor with 1 Parameter


I am trying to call a constructor with 1 parameter. The Query without the contructor parameter returns the values as expected. However, if I want to call the class with the additional parameter, I get the result counts as expected, but the values are all set to defaults.

Employee.cs

        public Employee(AppSettings appSettings)
        {
            employeeRepo = new EmployeeRepo(appSettings);
        }

        public Employee()
        {

        }

Database Call in the Repository

using (SqlConnection dbConnection = new SqlConnection(ConnectionString))
            {
                string sQuery = "select * from dbo.tblEmployees";;

                var result = dbConnection.Query<Employee>(sQuery).Select(row => new Employee(_appSettings));
                var result2 = dbConnection.Query<Employee>(sQuery);
            }

var Result - With empty Constructor
var Result2 - Calling constructor with parameter

I've tried various implementations of the above. I was initially brought to the custom constructor call by this post: Call custom constructor with Dapper?

I also tried fully qualifying the select statement and that didn't seem to work either based on this post: Dapper strongly typed Query returning default object values

I've also tried:

var result3 = dbConnection.Query<dynamic>(sQuery).Select(row => new Employee(_appSettings));

But anytime I started to use the Constructor with the parameter, I get the default values for all my objects back.


Solution

  • You should include property sets in .Select method. For exmaple:

      public class Employee
      {
        public int Id { get; set; }
        public string Name { get; set; }
        public AppSettings Settings { get; set; }
    
        public Employee() { }
        public Employee(AppSettings appSettings) { Settings = appSettings; }
    
        ...
        
        var result = dbConnection.Query<Employee>(sQuery).Select(row => new Employee(settings) {Id = row.Id, Name = row.Name});
      } 
    

    Also you can use AutoMapper for avoiding complex setter's calls:

          var config = new MapperConfiguration(cfg => cfg.CreateMap<Employee, Employee>()
            .ForMember(x => x.Settings, opt => opt.Ignore()));
    
          var mapper = config.CreateMapper();
    
          var result = dbConnection.Query<Employee>(sQuery).Select(row =>
          {
            var obj = new Employee(settings);
            return mapper.Map(row, obj);
          });