无法隐式转换 ICollection 类型
为了清楚地理解,这就是我想要实现的目标:我想要创建一个名为 TblMeter 的表,该表具有以下关系:
- 与表 TblMeter 的一对一关系、
- 与表 TblParameter 的一对多关系、
- 一对多关系与表 TblRegister 的关系
这是我的数据模型:
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; }
}
我期望得到一个 MeterDetail
,它有一个 Meter
、一个 Parameter
列表,以及一个列表注册
。
运行 API 并尝试创建 MeterDetail
时,我在 Web api 中收到此错误:
无法隐式转换类型“System.Collections.Generic.ICollection
”到“System.Collections.Generic.ICollection ”。存在显式转换(您是否缺少强制转换?)
我应该如何正确地从 ICollection
转换为 ICollection
?
问题是由我的 EF 数据模型声明引起的吗?
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; }
}
服务:
public TblMeterDetail GetMeterDetailById(int ParamId)
{
return _db.MeterDetails.Find(ParamId);
}
这是用于通过 id 获取仪表详细信息的控制器/api:
[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);
}
错误位于映射器
映射器上:
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,
};
}
}
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,
};
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在
SerializeMeterDetailModel
中,您传入一个TblMeterDetail
对象。TblMeterDetail
具有ParamRegister
的属性,其类型为ICollection
。但随后在SerializeMeterDetailModel
中,您将ParamRegister
作为类型ICollection
读取。这就是为什么您会遇到类型不匹配/无法转换的原因。换句话说,该属性作为一种类型传入,但您试图将其作为不同的类型进行处理。老实说,我不太清楚你在做什么,也不知道你所谓的“数据模型”和“DTO”之间有什么区别。也许“DTO”是视图模型?无论如何,您需要将传入类型转换为所需类型。
您可以在 DTO 类型的构造函数中执行此操作(即,如果您要在多个中执行此操作,则将
TblMeterDetail
对象传递给MeterDetailModel
的构造函数地方,或者在您的SerializeMeterDetailModel
方法中(如果它刚刚发生在那里),即:In
SerializeMeterDetailModel
, you are passing in aTblMeterDetail
object.TblMeterDetail
has a property ofParamRegister
that is of typeICollection<TblRegister>
. But then in theSerializeMeterDetailModel
you are readingParamRegister
as typeICollection<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 ofMeterDetailModel
if you're going to do it in more than one place, or in yourSerializeMeterDetailModel
method if it's just happening there. ie something like: