当我更新相关记录时,我注意到更新后,主键被重新分配。后者是long
中的RecordId
数据类型(PartnersRegistry
中的示例await unitOfWork.CompleteAsync();
),我注意到保存更改后其值已更改。看起来EF正在删除旧的实体对象并添加新的实体对象,而不仅仅是更新更改(下例中的Primary Key
)。
我有两个问题:
[Table("PatientsRegistry")]
public class PatientRegistry
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Display(Name = "Record Id")]
public long RecordId { get; set; }
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
[Display(Name = "Patient File Number")]
public long PatientFileId { get; set; }
public DateTimeOffset DateCreated { get; set; }
[Timestamp]
public byte[] RowVersion { get; set; }
public virtual ICollection<PartnerRegistry> Partners { get; set; }
}
是什么?我发布相关代码:
[Table("PartnersRegistry")]
public class PartnerRegistry
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long RecordId { get; set; }
public long PatientFileId { get; set; }
public long PartnerFileId { get; set; }
[JsonIgnore]
public virtual PatientRegistry PatientsRegistry { get; set; }
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
}
[HttpPut]
public async Task<IActionResult> UpdatePatient(long fileId, [FromBody] SavePatientsRegistryViewModel model)
{
SuccessResponse response = new SuccessResponse();
if (!ModelState.IsValid)
return StatusCode(400, StaticHandlers.FormatErrorResponse(ModelState));
PatientRegistry patient = await repository.GetPatient(fileId);
if (patient == null)
{
ModelState.AddModelError(string.Empty, "The patient does not exist in the database");
return StatusCode(404, StaticHandlers.FormatErrorResponse(ModelState));
}
model.PatientFileId = patient.PatientFileId;
PatientRegistry modelPatientRegistryData = mapper.Map<SavePatientsRegistryViewModel, PatientRegistry>(model, patient);
await unitOfWork.CompleteAsync();
response.SuccessMessage = patient.FirstName + " " + patient.LastName + " has been updated successfully!";
response.DataResponse = patient.PatientFileId;
return StatusCode(200, response);
}
public class SavePatientsRegistryViewModel
{
public long PatientFileId { get; set; }
public ICollection<SavePartnerRegistryViewModel> Partners { get; set; }
public OnlineAccountViewModel OnlineAccount { get; set; }
public SavePatientsRegistryViewModel()
{
Partners = new Collection<SavePartnerRegistryViewModel>();
}
}
public class SavePartnerRegistryViewModel
{
public string RecordId { get; set; }
public long PatientFileId { get; set; }
public long PartnerFileId { get; set; }
public string StartDate { get; set; }
public string EndDate { get; set; }
}
这些是控制器使用的视图模型:
CreateMap<SavePatientsRegistryViewModel, PatientRegistry>()
.ForMember(pr => pr.RecordId, opt => opt.Ignore())
.ForMember(pr => pr.PatientFileId, opt => opt.Ignore())
.ForMember(pr => pr.UserId, opt => opt.Ignore())
.ForMember(pr => pr.Partners, opt => opt.MapFrom(c => c.Partners))
.ForMember(pr => pr.User, opt => opt.MapFrom(c => c.OnlineAccount));
CreateMap<SavePartnerRegistryViewModel, PartnerRegistry>()
.ForMember(pr => pr.RecordId, opt => opt.Ignore())
.ForMember(pr => pr.PatientFileId, opt => opt.Ignore())
.ForMember(pr => pr.PatientFileId, opt => opt.MapFrom(s => s.PatientFileId))
.ForMember(pr => pr.PartnerFileId, opt => opt.MapFrom(s => s.PartnerFileId))
.ForMember(pr => pr.StartDate, opt => opt.MapFrom(s => s.StartDate))
.ForMember(pr => pr.EndDate, opt => opt.MapFrom(s => s.EndDate));
我的映射配置文件是:
await unitOfWork.CompleteAsync();
基本上,我在控制器中的更新方法中执行的操作如下:
我通过从Dbcontext调用来检查患者是否存在。
我将视图模型映射到实体。
映射后,值会发生变化,我会调用await context.SaveChangesAsync();
,这基本上是PartnerRegistry
我的问题出在相关表格中(RecordId
)。保存更改后,作为PK的列RecordId
将获得新值。现在,EF没有确定更新此列,即使我尝试,我也会收到错误消息,说明自动生成后无法在此字段中插入值!
{
"patientFileId": 1111,
"partners": [
{
"recordId": **5**,
"patientFileId": 1111,
"partnerFileId": 2222,
"startDate": "1/1/90 12:00:00 AM",
"endDate": "1/1/00 12:00:00 AM",
"patientName": null
}
]
}
更改其值的唯一方法是插入,删除并重新插入整个记录。
以下示例。
在更新之前:
{
"patientFileId": 1111,
"partners": [
{
"recordId": **6**,
"patientFileId": 1111,
"partnerFileId": 2222,
"startDate": "1/1/90 12:00:00 AM",
"endDate": "1/1/00 12:00:00 AM",
"patientName": null
}
]
}
更新后:
Partners
调试后,我发现映射后重新初始化了PatientRegistry patient = await repository.GetPatient(fileId);
集合!
Partners
此处的ICollection
集合与上下文中的相同。但是,在映射之后,由于某种原因,整个PatientRegistry modelPatientRegistryData = mapper.Map<SavePatientsRegistryViewModel, PatientRegistry>(model, patient);
被重新初始化。具体来说:
public class AudioPlayer {
Long currentFrame;
Clip clip;
// current status of clip
String status;
AudioInputStream musicInputStream;
// constructor to initialize streams and clip
public AudioPlayer(Schedule schedule,List<File> files)
throws UnsupportedAudioFileException,
IOException, LineUnavailableException
{
// create AudioInputStream object
musicInputStream =
AudioSystem.getAudioInputStream(files.get(0).getAbsoluteFile());
// create clip reference
clip = AudioSystem.getClip();
// open audioInputStream to the clip
clip.open(musicInputStream);
clip.loop(Clip.LOOP_CONTINUOUSLY);
}
}
答案 0 :(得分:0)
正如@smit所说,AutoMapper
在映射后创建了一个新集合,而不是修改现有集合。类似的问题描述为here,
我的解决方法如下,
我忽略了集合的映射,然后在这里手动评估记录操作,(插入/更新/删除)
// CreateMap<SavePartnerRegistryViewModel, PartnerRegistry> ();
不再需要。
CreateMap<SavePatientsRegistryViewModel, PatientRegistry> ()
.ForMember (d => d.RecordId, opt => opt.Ignore ())
.ForMember (d => d.PatientFileId, opt => opt.Ignore ())
.ForMember (d => d.UserId, opt => opt.Ignore ())
.ForMember (d => d.Partners, opt => opt.Ignore ())
.ForMember (d => d.User, opt => opt.MapFrom (s => s.OnlineAccount))
.AfterMap ((s, d) => {
// check if context object is included in the model? if not prime for delete.
foreach (PartnerRegistry partner in d.Partners.ToList ()) {
SavePartnerRegistryViewModel modelPartner = s.Partners.SingleOrDefault (c => c.PatientFileId == partner.PatientFileId && c.PartnerFileId == partner.PartnerFileId);
if (!s.Partners.Contains (modelPartner)) {
d.Partners.Remove (partner);
}
}
// check if model object(s) is/are included in the context?
foreach (SavePartnerRegistryViewModel modelPartner in s.Partners) {
PartnerRegistry partner = d.Partners.SingleOrDefault (c => c.PatientFileId == modelPartner.PatientFileId && c.PartnerFileId == modelPartner.PartnerFileId);
// if yes, prime for update
if (d.Partners.Contains (partner)) {
partner.PartnerFileId = modelPartner.PartnerFileId;
partner.StartDate = DateTime.Parse (modelPartner.StartDate);
partner.EndDate = string.IsNullOrWhiteSpace (modelPartner.EndDate) ? (DateTime?) null : DateTime.Parse (modelPartner.EndDate);
} else {
// if Not, prime for insert
d.Partners.Add (
new PartnerRegistry {
PatientFileId = modelPartner.PatientFileId,
PartnerFileId = modelPartner.PartnerFileId,
StartDate = DateTime.Parse (modelPartner.StartDate),
EndDate = string.IsNullOrWhiteSpace (modelPartner.EndDate) ? (DateTime?) null : DateTime.Parse (modelPartner.EndDate)
}
);
}
}
});