0

For a clear understanding, this is what I'm trying to achieve: I want to make a have a table called TblMeter that has a relationship of:

  • one to one relationship to table TblMeter,
  • one to many relationships to table TblParameter,
  • one to many relationships to table TblRegister

This is my data model:

public class TblMeterDetail
{
    [Key]
    public int ParamId { get; set; }
    public int ParamMeterId { get; set; }
    public TblMeter ParamMeter { get; set; }
    public virtual ICollection<TblParameter>  ParamParameter { get; set; }
    public virtual ICollection<TblRegister>  ParamRegister { get; set; }
    public bool IsArchive { get; set; }
    public DateTime CreatedOn { get; set; }
    public DateTime UpdatedOn { get; set; }
}

What I'm expecting is to get a MeterDetail that has one Meter, a list of Parameter, and a list of Register.

When running the API and trying to create a MeterDetail, I get this error in my web api:

Cannot implicitly convert type 'System.Collections.Generic.ICollection<OamrBackend.Web.ViewModels.RegisterModel>' to 'System.Collections.Generic.ICollection<OamrBackend.Data.Models.TblRegister>'. An explicit conversion exists (are you missing a cast?)

How should I convert from ICollection<TblParameter> to ICollection<ParameterModel> correctly?

Is the problem caused by my EF Data Model declaration?

DTO:

public class MeterDetailModel
{
    public int ParamId { get; set; }
    public int ParamMeterId { get; set; }
    public MeterModel ParamMeter { get; set; }
    public virtual ICollection<ParameterModel> ParamParameter { get; set; }
    public virtual ICollection<RegisterModel> ParamRegister { get; set; }
    public bool IsArchive { get; set; }
    public DateTime CreatedOn { get; set; }
    public DateTime UpdatedOn { get; set; }
}

Service:

public TblMeterDetail GetMeterDetailById(int ParamId)
{
    return _db.MeterDetails.Find(ParamId);
}

This is the controller/api for getting meter detail by id:

        [HttpGet("api/meterdetail/{ParamId}")]
        public ActionResult GetTblMeterDetailById(int ParamId)
        {
            _logger.LogInformation("Getting Meter Detail based on Id");
            var meterDetail = _meterDetailService.GetMeterDetailById(ParamId);
            var meterDetailData = MeterDetailMapper.SerializeMeterDetailModel(meterDetail);
            return Ok(meterDetailData);
        }

The error is here on the mapper

Mapper:

public class MeterDetailMapper
    {
        public static MeterDetailModel SerializeMeterDetailModel(TblMeterDetail meterDetail)
        {
            return new MeterDetailModel
            {
                ParamId = meterDetail.ParamId,
                ParamMeter = MapMeter(meterDetail.ParamMeter),
                ParamParameter = (ICollection<ParameterModel>)meterDetail.ParamParameter, <- error here
                ParamRegister = (ICollection<RegisterModel>)meterDetail.ParamRegister, <- error here
                IsArchive = meterDetail.IsArchive,
                CreatedOn = meterDetail.CreatedOn,
                UpdatedOn = meterDetail.UpdatedOn,
            };

        }

        public static TblMeterDetail SerializeMeterDetailModel(MeterDetailModel meterDetail)
        {
            return new TblMeterDetail
            {
                ParamId = meterDetail.ParamId,
                ParamMeter = MapMeter(meterDetail.ParamMeter),
                ParamParameter = (ICollection<TblParameter>)meterDetail.ParamParameter, <- error here
                ParamRegister = (ICollection<TblRegister>)meterDetail.ParamRegister, <- error here
                IsArchive = meterDetail.IsArchive,
                CreatedOn = meterDetail.CreatedOn,
                UpdatedOn = meterDetail.UpdatedOn,
            };

        }

        public static MeterModel MapMeter(TblMeter meter)
        {
            return new MeterModel
            {
                ParamId = meter.ParamId,
                ParamMeterId = meter.ParamMeterId,
                ParamMeterName = meter.ParamMeterName,
                ParamDeviceType = meter.ParamDeviceType,
                IsArchive = meter.IsArchive,
                CreatedOn = meter.CreatedOn,
                UpdatedOn = meter.UpdatedOn,
            };

        }
        public static TblMeter MapMeter(MeterModel meter)
        {
            return new TblMeter
            {
                ParamId = meter.ParamId,
                ParamMeterId = meter.ParamMeterId,
                ParamMeterName = meter.ParamMeterName,
                ParamDeviceType = meter.ParamDeviceType,
                IsArchive = meter.IsArchive,
                CreatedOn = meter.CreatedOn,
                UpdatedOn = meter.UpdatedOn,
            };

        }
    }
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Daniel
  • 109
  • 1
  • 13

1 Answers1

0

In SerializeMeterDetailModel, you are passing in a TblMeterDetail object. TblMeterDetail has a property of ParamRegister that is of type ICollection<TblRegister>. But then in the SerializeMeterDetailModel you are reading ParamRegister as type ICollection<RegisterModel>. That's why you're getting the type mismatch / unable to convert. In other words, that property is being passed in as one type, but you're trying to handle it as a different type.

I honestly don't know quite what you're doing, and what the difference between what you call your 'data model' and your 'DTO' are. Maybe the 'DTO's are view models? Regardless, you will need to translate the incoming types to the desired types.

You can do this in the constructor of the DTO type (ie, pass in a TblMeterDetail object to the constructor of MeterDetailModel if you're going to do it in more than one place, or in your SerializeMeterDetailModel method if it's just happening there. ie something like:

 ParamRegister = meterDetail.ParamRegister
     .Select(i=>new RegisterModel{
        propertyA = i.propertyA,
        propertyB = i.propertyB,
        etc}
     ).ToList(); <- error here
Jonathan
  • 4,916
  • 2
  • 20
  • 37