私はこの数日間、この問題に苦労しています。 WebAPI APIと通信するWebアプリケーションがあり、 "Entity Framework Reverse POCO CodeFirst Generator"ビジュアルスタジオ拡張によって作成および維持されるエンティティを取得および更新します。それらはすべてエンティティとDbContextを生成するようです。しかしここに問題があります:Webクライアントは、 "Patient"エンティティを返すAPIメソッドにajax呼び出しを行います。この患者エンティティには、NULLIableとPharmacyIdの2つのヌル入力可能な外部キーがあります。今、患者がリポジトリによって取り出されるとき、それはサーバの上でよく見えます。 LanguageIdとPharmacyIdは期待通りにnullです。患者のナビゲーションプロパティ、すなわちluLanguageとPharmacyも正しくnullに設定されます。クライアントが受け取ったjsonオブジェクトも今度はのように見えます。外部キーIdとナビゲーションプロパティの両方がnullです。クライアントは、患者オブジェクトに対するいくつかのオプションの編集を行い、オブジェクトをサーバーにPOSTして戻します。 POST ajax呼び出しが行われる直前に、患者のjsonオブジェクトはまだ正常に見えます。。外部キーとナビゲーションプロパティはnullです。しかし、そのオブジェクトがWebAPIメソッドによって受信されるとすぐに、不思議なことに空の言語と薬局のナビゲーションプロパティがあります。外部キーに対応する主キーはINTであるため、0で初期化されます。これにより、言語の外部キーと言語ナビゲーションオブジェクトの主キーが一致しないため、DbContextを更新しようとすると気が狂ってしまいます。 1つはヌルで、もう1つは0(ゼロ)です。私は非常に多くの異なるテストを試みましたが、どのようにカットしても同じ問題に戻ります。EF6がヌル可能な外部キーの空の子エンティティを生成しています
エンティティモデルビルダーの設定コードは次のとおりです。
public PatientConfiguration(string schema)
{
ToTable("Patient", schema);
HasKey(x => x.Id);
Property(x => x.Id).HasColumnName(@"ID").IsRequired().HasColumnType("bigint").HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity);
Property(x => x.LastName).HasColumnName(@"LastName").IsOptional().IsUnicode(false).HasColumnType("varchar").HasMaxLength(50);
Property(x => x.FirstName).HasColumnName(@"FirstName").IsOptional().IsUnicode(false).HasColumnType("varchar").HasMaxLength(50);
Property(x => x.MiddleName).HasColumnName(@"MiddleName").IsOptional().IsUnicode(false).HasColumnType("varchar").HasMaxLength(30);
Property(x => x.Gender).HasColumnName(@"Gender").IsOptional().IsUnicode(false).HasColumnType("varchar").HasMaxLength(18);
Property(x => x.Dob).HasColumnName(@"DOB").IsRequired().HasColumnType("datetime");
Property(x => x.SocialSecurity).HasColumnName(@"SocialSecurity").IsOptional().HasColumnType("varbinary");
Property(x => x.LastFourSsn).HasColumnName(@"LastFourSSN").IsOptional().HasColumnType("int");
Property(x => x.PharmacyId).HasColumnName(@"PharmacyID").IsOptional().HasColumnType("bigint");
Property(x => x.InUseById).HasColumnName(@"InUseByID").IsOptional().HasColumnType("bigint");
Property(x => x.LanguageId).HasColumnName(@"LanguageID").IsOptional().HasColumnType("int");
Property(x => x.Status).HasColumnName(@"Status").IsOptional().IsUnicode(false).HasColumnType("varchar").HasMaxLength(10);
Property(x => x.IsInactive).HasColumnName(@"IsInactive").IsRequired().HasColumnType("bit");
Property(x => x.CreatedById).HasColumnName(@"CreatedByID").IsRequired().HasColumnType("bigint");
Property(x => x.CreatedDate).HasColumnName(@"CreatedDate").IsRequired().HasColumnType("datetime");
Property(x => x.UpdatedById).HasColumnName(@"UpdatedByID").IsRequired().HasColumnType("bigint");
Property(x => x.UpdatedDate).HasColumnName(@"UpdatedDate").IsRequired().HasColumnType("datetime");
Property(x => x.MigratedBy).HasColumnName(@"MigratedBy").IsOptional().IsUnicode(false).HasColumnType("varchar").HasMaxLength(10);
Property(x => x.TimeStamped).HasColumnName(@"TimeStamped").IsRequired().IsFixedLength().HasColumnType("timestamp").HasMaxLength(8).IsRowVersion().HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Computed);
// Foreign keys
HasOptional(a => a.LuLanguage).WithMany(b => b.Patients).HasForeignKey(c => c.LanguageId).WillCascadeOnDelete(false); // FK_Patient_luLanguage
HasOptional(a => a.Pharmacy).WithMany(b => b.Patients).HasForeignKey(c => c.PharmacyId).WillCascadeOnDelete(false); // FK_Pharmacy_Patient
InitializePartial();
}
そして、ここで生成された患者のエンティティ
あるpublic partial class Patient : EntityBase
{
//[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; } // ID (Primary key)
public string LastName { get; set; } // LastName (length: 50)
public string FirstName { get; set; } // FirstName (length: 50)
public string MiddleName { get; set; } // MiddleName (length: 30)
public string Gender { get; set; } // Gender (length: 18)
public System.DateTime Dob { get; set; } // DOB
public byte[] SocialSecurity { get; set; } // SocialSecurity
public int? LastFourSsn { get; set; } // LastFourSSN
public long? PharmacyId { get; set; } // PharmacyID
public long? InUseById { get; set; } // InUseByID
public int? LanguageId { get; set; } // LanguageID
public string Status { get; set; } // Status (length: 10)
public bool IsInactive { get; set; } // IsInactive
public long CreatedById { get; set; } // CreatedByID
public System.DateTime CreatedDate { get; set; } // CreatedDate
public long UpdatedById { get; set; } // UpdatedByID
public System.DateTime UpdatedDate { get; set; } // UpdatedDate
public string MigratedBy { get; set; } // MigratedBy (length: 10)
public byte[] TimeStamped { get; private set; } // TimeStamped (length: 8)
// Reverse navigation
public virtual System.Collections.Generic.ICollection<AuditPatientChange> AuditPatientChanges { get; set; } // auditPatientChange.R_88
public virtual System.Collections.Generic.ICollection<PatientAddress> PatientAddresses { get; set; } // PatientAddress.FK_PatientAddress_Patient
public virtual System.Collections.Generic.ICollection<PatientCallTracking> PatientCallTrackings { get; set; } // PatientCallTracking.R_74
public virtual System.Collections.Generic.ICollection<PatientContact> PatientContacts { get; set; } // PatientContact.FK_PatientContact_Patient
public virtual System.Collections.Generic.ICollection<PatientCreditCard> PatientCreditCards { get; set; } // PatientCreditCard.R_59
public virtual System.Collections.Generic.ICollection<PatientDiseaseState> PatientDiseaseStates { get; set; } // PatientDiseaseState.R_65
public virtual System.Collections.Generic.ICollection<PatientIcd10> PatientIcd10 { get; set; } // PatientICD10.R_63
public virtual System.Collections.Generic.ICollection<PatientMedicalHistory> PatientMedicalHistories { get; set; } // PatientMedicalHistory.R_60
public virtual System.Collections.Generic.ICollection<PatientNoteAndComment> PatientNoteAndComments { get; set; } // PatientNoteAndComment.R_73
public virtual System.Collections.Generic.ICollection<PatientPayment> PatientPayments { get; set; } // PatientPayment.R_56
public virtual System.Collections.Generic.ICollection<PatientPlanPolicy> PatientPlanPolicies { get; set; } // PatientPlanPolicy.R_90
public virtual System.Collections.Generic.ICollection<PatientReferral> PatientReferrals { get; set; } // PatientReferral.FK_PatientReferral_Patient
public virtual System.Collections.Generic.ICollection<PatientShareOfCost> PatientShareOfCosts { get; set; } // PatientShareOfCost.R_62
public virtual System.Collections.Generic.ICollection<Rx> Rxes { get; set; } // Rx.FK_Rx_Patient
// Foreign keys
public virtual LuLanguage LuLanguage { get; set; } // FK_Patient_luLanguage
public virtual Pharmacy Pharmacy { get; set; } // FK_Pharmacy_Patient
public Patient()
{
IsInactive = false;
CreatedById = 0;
UpdatedById = 0;
AuditPatientChanges = new System.Collections.Generic.List<AuditPatientChange>();
PatientAddresses = new System.Collections.Generic.List<PatientAddress>();
PatientCallTrackings = new System.Collections.Generic.List<PatientCallTracking>();
PatientContacts = new System.Collections.Generic.List<PatientContact>();
PatientCreditCards = new System.Collections.Generic.List<PatientCreditCard>();
PatientDiseaseStates = new System.Collections.Generic.List<PatientDiseaseState>();
PatientIcd10 = new System.Collections.Generic.List<PatientIcd10>();
PatientMedicalHistories = new System.Collections.Generic.List<PatientMedicalHistory>();
PatientNoteAndComments = new System.Collections.Generic.List<PatientNoteAndComment>();
PatientPayments = new System.Collections.Generic.List<PatientPayment>();
PatientPlanPolicies = new System.Collections.Generic.List<PatientPlanPolicy>();
PatientReferrals = new System.Collections.Generic.List<PatientReferral>();
PatientShareOfCosts = new System.Collections.Generic.List<PatientShareOfCost>();
Rxes = new System.Collections.Generic.List<Rx>();
InitializePartial();
}
partial void InitializePartial();
}
、ここで、この問題をテストするJavaScriptコード、クライアント側である:
function testx1(){
var patient;
$.ajax({
type: 'GET',
url: "/api/patient/patient/61143",
success: function (result) {
patient = result;
testx2(patient);
},
error: function (xhr, options, error) {
debugger;
alert(error);
}
});
}
function testx2(patient) {
patient.LastFourSsn = 5555;
patient.ObjectStateEnum = 2;
var x = "adsf";
$.ajax({
type: 'POST',
url: "/api/patient/patient",
data: patient,
dataType: "json",
success: function (result) {
},
error: function (xhr, options, error) {
}
});
}
マイWebAPIのコード:
[Route("patient/{id}")]
[HttpGet]
public async Task<IHttpActionResult> GetPatientByIdAsync(long id)
{
try
{
var patient = await patientService.GetPatientByIdAsync(id);
if (patient == null)
return NotFound();
return Ok(patient);
}
catch (Exception ex)
{
return InternalServerError();
}
}
[Route("patient")]
[HttpPost]
public async Task<IHttpActionResult> SavePatient(Patient patient)
{
try
{
//if (patient.LanguageId == null && patient.LuLanguage?.Id == 0)
// patient.LuLanguage = null;
//if (patient.PharmacyId == null && patient.Pharmacy?.Id == 0)
// patient.Pharmacy = null;
IOperationStatus result = await patientService.UpdateAndSavePatientAsync(patient);
if (!result.Success)
return InternalServerError(new Exception(result.Message));
else
return Ok();
}
catch (Exception ex)
{
return InternalServerError(ex);
}
}
}
ここは私ですJsonシリアライザの設定:
public class BrowserJsonFormatter : JsonMediaTypeFormatter
{
public BrowserJsonFormatter()
{
this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
this.SerializerSettings.Formatting = Formatting.Indented;
}
public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
{
base.SetDefaultContentHeaders(type, headers, mediaType);
headers.ContentType = new MediaTypeHeaderValue("application/json");
}
}
実際のwebapiメソッドコードも含めることができますか? –
@Wiktor:WebAPIのメソッドコードを含めるために投稿を編集しました。ありがとう。 –
'SavePatient'を呼び出すと、バインドされたパラメータ' patient'にはすでに間違った値(nullではなく0)がありますか? –