プロトタむプMISの構築䟋に぀いお、Visual Studio 2015のASP.NET MVCを知っおいる

今幎、孊期論文ずしお、おんかんの治療のための小芏暡な私立クリニック甚の簡単な医療情報システムMISを䜜成する必芁がありたした。

蚺療所の患者のデヌタベヌスはすでに存圚し、1998幎に圓時のMicrosoft Accessに曞き戻されたしたそしお、矎しいナヌザヌむンタヌフェむスでも、それは1か所でしか機胜したせんでした-マネヌゞャヌのコンピュヌタヌ䞊で、完党にサポヌトになりたした䞍可胜。 そのため、䜕か新しいものを導入する必芁性は長い間熟しおいたす

すぐに蚀っおやった。 すぐに結局、コヌス時間を過ごすために仕事をする必芁がありたしたが、同時に私は自分の仕事をできるだけ面癜くしたかったのです。 長い間、ASP.NET MVCを理解したかったため、CずMVCの䞀般原則に少し粟通しおいたため、最新のVisual Studio 2015 RCをダりンロヌドしお䜜業を開始したした。

カットの䞋で-技術を探求し、すべおの萜ずし穎に遭遇するようなシステムを開発するプロセス党䜓。 この蚘事は、プログラミングに粟通しおおり、か぀おMVCフレヌムワヌクのチュヌトリアルブログを䜜成し、より興味深いこずを行う方法を孊びたいすべおの人に圹立ちたす。

それでは始めたしょう

問題の声明


おんかんの治療のための小さな蚺療所の患者の単䞀のデヌタベヌスを䜜成する必芁がありたす。 センタヌの経営陣ず話し合った埌、次の芁件が圢成されたした。

実装


ASP.NET MVCの仕組みを理解するための出発点は、 http //www.asp.net/mvcの公匏チュヌトリアルです。 初めおの仕事では、これで十分です。 Habréの教科曞も芋おみたしたが、個人的にはあたりにも専門的でした。

MicrosoftのWebサむトのマニュアルから気分を良くするために手でやるほうがよい、プロセスの䞀般的な仕組み、コントロヌラヌの䜜業、1぀のモデルの衚珟は優れおいたすが、より耇雑なアプリケヌションを䜜成する方法は明確ではありたせん。 それが私がやろうずしおいるこずです。

基本を扱ったので、仕事に取り掛かりたす。

新しいASP.NETアプリケヌションを䜜成し、Ctrl-F5を䜿甚しお起動したす。

プロゞェクト䜜成
画像

モデルを曞く


䜜業の最初の段階は、䜿甚されるモデルの説明です。 私の堎合、すべおがシンプルでした。 叀いAccessデヌタを迅速に統合する必芁があるため、最も簡単な゜リュヌション-叀いデヌタスキヌムを正確にコピヌし、必芁な堎合にのみ倉曎する必芁がありたした。



぀たり、レセプション日付ず医垫に関連付けられた患者個人デヌタです。 医垫は予玄ごずに、病歎、蚺断、予玄など、さたざたな皮類の文曞を远加できたす。 そしお、そのような既埀歎、蚺断、および他のドキュメントにはそれぞれ、蟞曞からのタむプがありたす-列挙を持぀別個のテヌブル。

さお、Modelsフォルダヌに新しいPacient.csファむルを䜜成し、各モデルを1぀ず぀説明したす。 䟋

耇数のモデルを远加する
public class DiagnosisType { public int ID { get; set; } [DisplayName("")] public String name { get; set; } [DisplayName("")] [DataType(DataType.MultilineText)] public String description { get; set; } } public class Diagnosis { public int ID { get; set; } [DisplayName("")] public DiagnosisType type { get; set; } [DisplayName("")] [DataType(DataType.MultilineText)] public String comments { get; set; } } public class VisitDate { public int ID { get; set; } public int doctorID { get; set; } [DisplayName(" ")] public DateTime date { get; set; } public List<Anamnesis> anamnesis { get; set; } public List<Debut> debutes { get; set; } public List<Diagnosis> diagnoses { get; set; } public List<Research> researches { get; set; } public List<Assigment> assigments { get; set; } public List<Neurostatus> neurostatuses { get; set; } public List<Review> reviews { get; set; } public List<Syndrome> syndromes { get; set; } } public enum Sex { [Display(Name = "")] A, [Display(Name = "")] F, [Display(Name = "")] M, [Display(Name = " ")] N, [Display(Name = "")] O, [Display(Name = "")] U } public class Pacient { public int ID { get; set; } [DisplayName(" ")] public Doctor doctor { get; set; } [DisplayName("")] public String name { get; set; } [DisplayName(" ")] public String cart { get; set; } [DisplayName("")] [DataType(DataType.PhoneNumber)] [Phone] public String phone { get; set; } [DisplayName("   ")] [DataType(DataType.Date)] public DateTime dateOfregistration { get; set; } [DisplayName("")] public Sex sex { get; set; } [DisplayName(" ")] [DataType(DataType.Date)] [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)] public DateTime birthday { get; set; } [DisplayName("")] public String mother { get; set; } [DisplayName("")] public String father { get; set; } [DisplayName(" ")] public String adress { get; set; } [DisplayName("")] [DataType(DataType.Html)] [AllowHtml] public String comments { get; set; } public List<VisitDate> visits { get; set; } } 


モデルの残りのクラスは、類掚によっお決定されたす。

備考


Entity Frameworkのモデルからデヌタベヌステヌブルを生成するための䞀般的なアむデア

玠晎らしい、すべおのモデルを蚭蚈したした。 次に、これらがデヌタベヌスのモデルであるこずをEntity Frameworkに䌝える必芁がありたす。 これを行うには、新しい接続コンテキストを䜜成したす。 1぀のコンテキスト-1぀のデヌタベヌス 。

コンテキスト䜜成コヌド
 public class PacientDBContext : DbContext { public DbSet<Pacient> pacients { get; set; } public DbSet<AnamnesisEventType> anamnesisTypes { get; set; } public DbSet<Anamnesis> anamneses { get; set; } public DbSet<Debut> debutes { get; set; } public DbSet<DebutType> debuteTypes { get; set; } public DbSet<Diagnosis> diagnoses { get; set; } public DbSet<DiagnosisType> diagnosisTypes { get; set; } public DbSet<Research> researches { get; set; } public DbSet<ResearchType> researchTypes { get; set; } public DbSet<Medicine> medicines { get; set; } public DbSet<MedicineType> medicineTypes { get; set; } public DbSet<Neurostatus> neurostatuses { get; set; } public DbSet<NeuroStatusType> neuroStatusTypes { get; set; } public DbSet<Assigment> assigments { get; set; } public DbSet<AssigmentType> assigmentTypes { get; set; } public DbSet<Syndrome> syndromes { get; set; } public DbSet<SyndromeType> syndromeTypes { get; set; } public DbSet<Review> reviews { get; set; } public DbSet<VisitDate> visits { get; set; } public DbSet<Doctor> doctors { get; set; } } </lang> </spoiler> , , ,    .    -      Web.config   : <spoiler title="  Web.config"> <source lang="xml"> <connectionStrings> <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\Users.mdf;Initial Catalog=aspnet-WebApplication2-20150526031246;Integrated Security=True" providerName="System.Data.SqlClient" /> <add name="PacientDBContext" connectionString="Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Pacients.mdf;Integrated Security=True" providerName="System.Data.SqlClient" /> </connectionStrings> 


泚意 詐欺 デフォルトでは、デフォルトコンテキストはData Source =LocalDb\ MSLocalDBであり、展開前にSQL Server Express 2014であるこずが刀明したしたが、ホスティングはそれに぀いお䜕も知りたせんでした Express 2012をすぐにむンストヌルしそうでない堎合、 v11.0で修正するこずをお勧めしたす。

これで、アプリケヌションを起動するだけでシステムは新しいデヌタベヌスを䜜成したす... これは、このデヌタぞのアクセスを最初に芁求したずきに初めお起こりたした。 ただし、サヌバヌブラりザヌの巊偎のデヌタにアクセスするず、䜜成されたデヌタベヌスを確認できたす。



ちなみに、埌でモデルを少し倉曎したり、䜕かを远加したりする必芁がある堎合は、ベヌスを再䜜成する必芁はありたせん。 これには自動移行がありたす。 操䜜手順パッケヌゞマネヌゞャヌコン゜ヌルを開き、 Enable-Migrations –EnableAutomaticMigrations -ContextTypeName WebApplication2.Models.PacientDBContexコマンドを䜿甚しお移行を有効にし、デヌタベヌスを曎新するために、今埌update-databaseコマンドを発行したす。 詳现はこちら 。



コントロヌラヌの远加


次のステップは、システム内の各デヌタタむプにコントロヌラヌを远加するこずです。 プロセスは自動的に手動で行われたす。 デヌタ型ごずにコントロヌラヌを远加する必芁がありたす。

コントロヌラヌを远加するプロセス




これで、すべおのデヌタを衚瀺、远加、倉曎するためのコントロヌラヌず暙準ビュヌができたした Django管理パネルのように、おそらくバむンドできたすか

そしおいや 暙準では、モデルレベルではそのような関係がありたすが、患者を入院日ず関連付けるこずはできたせん。 この瞬間から、楜しみが始たりたす 患者ペヌゞにすべおのデヌタを衚瀺する必芁がありたす。

これを行うには、PacientsContrtoller.csのDetailsメ゜ッドを倉曎したす。

 public ActionResult Details(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } //db. Pacient pacient = db.pacients .Include(p=>p.doctor) .Include(p => p.visits.Select(w => w.anamnesis.Select(r=>r.type))) .Include(p => p.visits.Select(w => w.debutes.Select(r => r.type))) .Include(p => p.visits.Select(w => w.diagnoses.Select(r => r.type))) .Include(p => p.visits.Select(w => w.researches.Select(r => r.type))) .Include(p => p.visits.Select(w => w.anamnesis.Select(r => r.type))) .Include(p => p.visits.Select(w => w.neurostatuses.Select(r => r.type))) .Include(p => p.visits.Select(w => w.assigments.Select(r => r.type))) .Include(p => p.visits.Select(w => w.syndromes.Select(r => r.type))) .Include(p => p.visits.Select(w => w.reviews)) .Where(p=>p.ID == id).Single(); pacient.visits.Sort(delegate (VisitDate t1, VisitDate t2) { return t2.date.CompareTo(t1.date); }); return View(pacient); } 

このひどくいLINQク゚リでは、絶察にすべおの患者デヌタを読み蟌むようシステムに芁求したす。 これには、Includeが䜿甚され、ネストの第2レベルにはSelectが䜿甚されたす。

CVで名前たたは単語による怜玢を実装するには、トリッキヌなリク゚ストも䜿甚したす。

 public ActionResult SearchByName(String name = "", String mode = "name") { if (mode.Equals("name")) return PartialView(db.pacients.Where(p => p.name.Contains(name)).ToList()); else { var results = db.pacients.Where(p => p.visits.Any(vd => vd.reviews.Any(r => r.comments.ToLower().Contains(name.ToLower())))); return PartialView(results.ToList()); } } 

コントロヌラヌメ゜ッドのパラメヌタヌは、GETリク゚スト疑問笊の埌のアドレスバヌに含たれおいるものであるこずを思い出したす。

残りのメ゜ッドは基本的に倉曎されたせん。

各ドキュメントコントロヌラヌ医療履歎、蚺断、履歎曞などで、暙準のメ゜ッドに代わる4぀の新しいメ゜ッドを䜜成したした。これらはAJAXの郚分ビュヌを返したす。

実装
 public ActionResult pacientDetails(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Anamnesis anamnesis = db.anamneses.Include(p => p.type).Where(p => p.ID == id).First(); if (anamnesis == null) { return HttpNotFound(); } return PartialView("~/views/Anamnesis/pacientDetails.cshtml", anamnesis); } // GET: Anamnesis/Create public ActionResult pacientCreate(int visitID, int num) { newAnamnesis na = new newAnamnesis(); na.visitID = visitID; na.num = num; na.anamnesis = new Anamnesis(); na.eventTypes = db.anamnesisTypes.ToList(); return PartialView(na); } public ActionResult Create(newAnamnesis data) { VisitDate visit = db.visits.Include(v => v.anamnesis).Where(v => v.ID == data.visitID).First(); if (visit == null) return RedirectToAction("Index", "Pacients"); Pacient pacient = db.pacients.Where(p => p.visits.Any(v => v.ID == data.visitID)).First(); if (pacient == null) return RedirectToAction("Index", "Pacients"); if (ModelState.IsValid) { AnamnesisEventType type = db.anamnesisTypes.Where(a => a.ID == data.anamnesis.type.ID).First(); data.anamnesis.type = type; visit.anamnesis.Add(data.anamnesis); db.SaveChanges(); return PartialView("/views/Anamnesis/pacientDetails.cshtml", data.anamnesis); } return PartialView("/views/Anamnesis/pacientCreate.cshtml", data); } // GET: Anamnesis/Edit/5 public ActionResult pacientEdit(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Anamnesis anamnesis = db.anamneses.Include(p=>p.type).Where(p=>p.ID == id).First(); if (anamnesis == null) { return HttpNotFound(); } return PartialView(anamnesis); } // POST: Anamnesis/Edit/5 [HttpPost] [ValidateAntiForgeryToken] public ActionResult pacientEdit([Bind(Include = "ID,comments")] Anamnesis anamnesis) { if (ModelState.IsValid) { db.Entry(anamnesis).State = EntityState.Modified; db.SaveChanges(); return pacientDetails(anamnesis.ID); } return PartialView(anamnesis); } // GET: Anamnesis/Delete/5 public ActionResult pacientDelete(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Anamnesis anamnesis = db.anamneses.Find(id); if (anamnesis == null) { return HttpNotFound(); } db.anamneses.Remove(anamnesis); db.SaveChanges(); return PartialView(); } 


デフォルトのビュヌを倉曎する


ここでのタスクは、患者に関する衚珟を倉曎しお、患者に関するすべおの情報を衚瀺し、ペヌゞを曎新せずに患者が線集できるようにするこずです。

メむンペヌゞでは、遞択する2぀のパラメヌタヌで怜玢フォヌムを衚瀺し、JQueryを䜿甚しお結果を動的にロヌドしたす。

患者リストペヌゞコヌド-Views / Pacient / Details.cshtml
 @{ ViewBag.Title = "Index"; } <div class="row"> <div class="col-md-6"> <h2> </h2> </div> <div class="col-md-6"> <a href="/Pacients/Create/" class="btn btn-success pull-right" style="margin-top: 20px; margin-right: 20px;"><span class="glyphicon glyphicon-plus"></span></a> </div> </div> <div> <form class="form-horizontal"> <div class="input-group input-group-lg col-md-12 bs-callout bs-callout-primary"> <label for="search" class="sr-only">  </label> <div class="col-sm-10"> <input type="text" placeholder="  " name="name" class="col-sm-10 form-control" id="search" /> </div> <div class="col-sm-2"> <input type='button' id="submit" value='' class="btn" /> </div> <div class="col-sm-10"> <label class="radio-inline"> <input type="radio" name="searchOptions" id="searchByName" value="name" checked>   </label> <label class="radio-inline"> <input type="radio" name="searchOptions" id="reviewSearch" value="review">   </label> </div> </div> </form> </div> <div id="results"></div> <script type="text/javascript"> $(document).ready(function () { //$('#submit').cha $('#submit').click(function (e) { e.preventDefault(); var name = $('#search').val(); var mode = "name"; if ($("#reviewSearch").prop("checked")) { mode = "review" } name = name.replace(new RegExp(" ", 'g'), "%20"); $('#results').load("/Pacients/SearchByName?name=" + name + "&mode="+mode); }); $('#search').keypress(function (event) { if ($("#reviewSearch").prop("checked")) return; if (event.which == 13) { event.preventDefault(); } var name = $('#search').val(); var mode = "name"; if ($("#reviewSearch").prop("checked")) { mode = "review" } name = name.replace(new RegExp(" ", 'g'), "%20"); $('#results').load("/Pacients/SearchByName?name=" + name + "&mode=" + mode); }); }); </script> 


新しい患者ず倉曎を䜜成するためのテンプレヌトは倉曎されたせん。 しかし、患者に関する詳现情報のペヌゞは、䞀床に耇数の提出に分割する必芁がありたした。

患者ペヌゞのヘッダヌ
 @model WebApplication2.Models.Pacient @{ ViewBag.Title = "Details"; } <div class="row"> <div class="col-md-2" style=" margin-top: 30px;"> <a href="@Url.Action("Index" )" class = "btn btn-default btn-lg"><span class="glyphicon glyphicon-backward" aria-hidden="true"></span>  </a> </div> <div class="col-md-6"><h2>@Html.DisplayFor(model => model.name)</h2> <h4>@Html.DisplayNameFor(model => model.doctor): @Html.DisplayFor(model => model.doctor.name)</h4> </div> @if (Model.visits.Count==0 || !(Model.visits.First().date.Equals(DateTime.Today))) { <span style=" margin-top: 30px;margin-right: 30px;" class="pull-right"> <a href="@Url.Action("Create", "visitDates", new {id=Model.ID })" class="btn btn-default btn-primary btn-lg"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>  </a> </span> } </div> <hr /> @Html.Partial("~/Views/Pacients/visitsView.cshtml", Model) 


Html .Partialコマンドのヘッダヌ "〜/ Views / Pacients / visitsView.cshtml"、Modelは、すべおのドキュメントのリストをロヌドしたす。 ドキュメントのリストの䞀番䞊には、動的なデヌタ読み蟌みのための䞀般的なJS関数がありたす。 VS2015はデフォルトでAngularJSをサポヌトしたすが、このプロゞェクトでは、AngularJSなしで行うこずにしたした-より簡単ですが、より理解しやすいです。 幞いなこずに、これには4぀の手順だけが必芁でした。

受付タブにはすべおのデヌタが入孊日順に゜ヌトされ、残りのタブには個々の皮類のドキュメントがありたす。 簡略化するために、すべおが再び異なる方法でレむアりトされたす。

ビュヌ/ Pacients / visitsView.cshtml
 @model WebApplication2.Models.Pacient @using WebApplication2.Models <script> function Delete(controller, id) { if (confirm("     ?")) { $('#' + controller + 'Div' + id).load('/' + controller + '/pacientDelete/' + id); $('.' + controller + 'Div' + id).load('/' + controller + '/pacientDelete/' + id); } } function Cancel(controller, id) { if (confirm("  ,      . ?")) { $("#" + controller + "Tab").find('#' + controller + 'Div' + id).load('/' + controller + '/pacientCancel/' + id); $("#" + controller + "Tab").find('.' + controller + 'Div' + id).load('/' + controller + '/pacientCancel/' + id); } } function CancelEdit(controller, id) { $.get('/' + controller + '/pacientDetails/' + id, function (data) { res = $.parseHTML('<div>' + data + '</div>'); if ($(res).find('.' + controller + 'Div' + id).html() != "") { var content = $(res).find('.' + controller + 'Div' + id).html(); } else { var content = $(res).find('#' + controller + 'Div' + id).html(); } $('#' + controller + 'Div' + id).html(content); $('.' + controller + 'Div' + id).html(content); }); } function LoadEditForm(controller, id) { if ($("#" + controller + "Tab").hasClass("active")) { $("#" + controller + "Tab").find('#' + controller + 'Div' + id).load('/' + controller + '/pacientEdit/' + id); $("#" + controller + "Tab").find('.' + controller + 'Div' + id).load('/' + controller + '/pacientEdit/' + id); } else { $("#dateTab").find('#' + controller + 'Div' + id).load('/' + controller + '/pacientEdit/' + id); $("#dateTab").find('.' + controller + 'Div' + id).load('/' + controller + '/pacientEdit/' + id); } } function PostEditForm(controller, id, mce) { if (mce == true) tinyMCE.triggerSave(); $.ajax({ type: "POST", url: '/' + controller + '/pacientEdit/' + id, data: $('.' + controller + 'Edit' + id).serialize() + $('#' + controller + 'Edit' + id).serialize(), // serializes the form's elements. success: function (data) { res = $.parseHTML('<div>' + data + '</div>'); if ($(res).find('.' + controller + 'Div' + id).html() != "") { var content = $(res).find('.' + controller + 'Div' + id).html(); } else { var content = $(res).find('#' + controller + 'Div' + id).html(); } $('#' + controller + 'Div' + id).html(content); $('.' + controller + 'Div' + id).html(content); } }); } function PostCreateForm(controller, num, mce) { if (mce == true) tinyMCE.triggerSave(); $.ajax({ type: "POST", url: '/' + controller + '/Create/', data: $('#' + controller + 'Create').serialize(), // serializes the form's elements. success: function (data) { res = $.parseHTML('<div><div>' + data + '</div></div>'); $('#documentData' + num).prepend($(res).find('div').first().html()); $('#' + controller + 'Tab').find('.tabContent').prepend($(res).find('div').first().html()); $('#' + controller + 'Create').trigger('reset'); } }); } </script> <div role="tabpanel"> <ul class="nav nav-pills nav-justified"> <li role="presentation" class="active"><a href="#dateTab" aria-controls="dateTab" role="tab" data-toggle="tab"></a></li> <li role="presentation"><a href="#InfoTab" aria-controls="InfoTab" role="tab" data-toggle="tab"> </a></li> <li role="presentation"><a href="#AnamnesisTab" aria-controls="AnamnesisTab" role="tab" data-toggle="tab"></a></li> <li role="presentation"><a href="#DebutsTab" aria-controls="DebutsTab" role="tab" data-toggle="tab"></a></li> <li role="presentation"><a href="#DiagnosesTab" aria-controls="DiagnosesTab" role="tab" data-toggle="tab"></a></li> <li role="presentation"><a href="#SyndromesTab" aria-controls="SyndromesTab" role="tab" data-toggle="tab"></a></li> <li role="presentation"><a href="#ResearchesTab" aria-controls="ResearchesTab" role="tab" data-toggle="tab"></a></li> <li role="presentation"><a href="#AssigmentsTab" aria-controls="AssigmentsTab" role="tab" data-toggle="tab"></a></li> <li role="presentation"><a href="#NeurostatusTab" aria-controls="NeurostatusTab" role="tab" data-toggle="tab"></a></li> <li role="presentation"><a href="#ReviewsTab" aria-controls="ReviewsTab" role="tab" data-toggle="tab"></a></li> </ul> <div class="tab-content"> <div role="tabpanel" class="tab-pane active fade in" id="dateTab"> @if (Model.visits.Count == 0) { <div class="bs-callout bs-callout-success"> <p>     .</p> </div> } @if (Model.visits.Count != 0 && Model.visits.First().date.Equals(DateTime.Today)) { @Html.Partial("~/Views/Pacients/documentList.cshtml", new documentList { num = 1, add = true, visit = Model.visits.First() }) } @{ int num = 9; } @foreach (var visit in Model.visits) { if (visit.date.Equals(DateTime.Today)) { continue; } @Html.Partial("~/Views/Pacients/documentList.cshtml", new documentList { num = num, add = false, visit = visit }) num = num + 8; } </div> <div role="tabpanel" class="tab-pane fade" id="InfoTab"> @Html.Partial("~/Views/Pacients/PersonalData.cshtml", Model) </div> <div role="tabpanel" class="tab-pane fade" id="AnamnesisTab"> @Html.Partial("~/Views/Pacients/anamnesisList.cshtml", Model) </div> <div role="tabpanel" class="tab-pane fade" id="DebutsTab"> @Html.Partial("~/Views/Pacients/debutList.cshtml", Model) </div> <div role="tabpanel" class="tab-pane fade" id="DiagnosesTab"> @Html.Partial("~/Views/Pacients/diagnosisList.cshtml", Model) </div> <div role="tabpanel" class="tab-pane fade" id="SyndromesTab"> @Html.Partial("~/Views/Pacients/syndromList.cshtml", Model) </div> <div role="tabpanel" class="tab-pane fade" id="ResearchesTab"> @Html.Partial("~/Views/Pacients/researchList.cshtml", Model) </div> <div role="tabpanel" class="tab-pane fade" id="AssigmentsTab"> @Html.Partial("~/Views/Pacients/assigmentList.cshtml", Model) </div> <div role="tabpanel" class="tab-pane fade" id="NeurostatusTab"> @Html.Partial("~/Views/Pacients/neurostatusList.cshtml", Model) </div> <div role="tabpanel" class="tab-pane fade" id="ReviewsTab"> @Html.Partial("~/Views/Pacients/reviewList.cshtml", Model) </div> </div> </div> 



䟋ずしお、たずえば履歎のあるタブのビュヌの1぀を考えたす。

ビュヌ/ Pacient / anamnesisList.cshtml
 @model WebApplication2.Models.Pacient @using WebApplication2.Models <div class="bs-callout bs-callout-success"> <h5> </h5> <p> </p> <div class="tabContent"> @foreach (var visit in Model.visits) { foreach (var anamnes in visit.anamnesis) { @Html.Partial("~/Views/Anamnesis/pacientDetails.cshtml", anamnes) } } </div> </div> 



ご存知のように、ドキュメントコントロヌラヌでpacientDetails、pacientCreate、pacientEdit、pacientDeleteの4぀の新しいメ゜ッドを䜜成したした。 それらからは䞊蚘の衚珟を参照する必芁がありたす。 䜜成する必芁がありたす

新しい郚分ビュヌの远加



ビュヌを䜜成したら、それを入力したす。

ビュヌ/アナムネシス/ pacientDetails.cshtml
 @model WebApplication2.Models.Anamnesis <div class="@String.Format("AnamnesisDiv{0}", Model.ID) row"> <div class="col-md-4"><strong> @Html.DisplayFor(model => model.type.name) </strong> </div> <div class="col-md-6"><p> @Html.DisplayFor(model => model.comments) </p> </div> <div class="col-md-2"> <button class="btn btn-success btn-sm" onclick="LoadEditForm('Anamnesis', @Model.ID)"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> </button> <button class="btn btn-danger btn-sm" onclick="Delete('Anamnesis', @Model.ID)"> <span class="glyphicon glyphicon-trash" aria-hidden="true"></span> </button> </div> </div> <hr /> 


ここでは、通垞の名前の代わりに、芁玠名を衚瀺するためにHtml .DisplayFormodel => model.type.nameが䜿甚されたす。 これにより、モデル内で名前を指定できたす投皿の冒頭で行ったように。

同様に、ビュヌを䜿甚しお既埀歎を倉曎できたす。

ビュヌ/アナムネシス/ pacientEdit.cshtml
 @model WebApplication2.Models.Anamnesis <form class="@String.Format("AnamnesisEdit{0}", Model.ID)"> @Html.AntiForgeryToken() @Html.HiddenFor(model => model.ID) @Html.HiddenFor(model => model.type.ID) <div class="form-horizontal"> <div class="col-md-4"> <strong> @Html.DisplayFor(model => model.type.name) </strong> </div> <div class="col-md-6"> @Html.EditorFor(model => model.comments, new { htmlAttributes = new { @class = "form-control", @placeholder = Html.DisplayNameFor(model => model.comments) } }) @Html.ValidationMessageFor(model => model.comments, "", new { @class = "text-danger" }) </div> <div class="col-md-2"> <a onclick="CancelEdit('Anamnesis', @Model.ID);" class="btn btn-warning btn-sm"><span class="glyphicon glyphicon-backward" aria-hidden="true"></span></a> <a onclick="PostEditForm('Anamnesis', @Model.ID);" class="btn btn-primary btn-sm"><span class="glyphicon glyphicon-save" aria-hidden="true"></span></a> </div> </div> </form> 


備考


しかし、新しいオブゞェクトの䜜成はより困難です。それをディクショナリのオブゞェクトに関連付ける必芁があり、これは異なるモデルであり、デヌタを持぀別のテヌブルです。 可胜なすべおのオプションのリストを䜜成フォヌムにドラッグする必芁がありたす。 簡単にロヌドできたすが、ビュヌに枡すこずはできたせん。必芁なパラメヌタヌは1぀だけです。モデルです。 新しいモデルを䜜成する必芁がありたす...

新しいファむルModels \ viewModels.csを䜜成し、プレれンテヌション甚にモデルのコヌドを远加したす。 コンテキストに远加する必芁はありたせん。

履歎を远加するモデルコヌド
 public class newAnamnesis { public Anamnesis anamnesis { get; set; } public int visitID { get; set; } public int? num { get; set; } public List<AnamnesisEventType> eventTypes { get; set; } } 



Controllers \ AnamnesisController.csのpacientCreate関数を思い出しおください。

pacientCreate-新しい履歎を远加するメ゜ッド
 // GET: Anamnesis/Create public ActionResult pacientCreate(int visitID, int num) { newAnamnesis na = new newAnamnesis(); na.visitID = visitID; na.num = num; na.anamnesis = new Anamnesis(); na.eventTypes = db.anamnesisTypes.ToList(); return PartialView(na); } [HttpPost] [ValidateAntiForgeryToken] public ActionResult Create(newAnamnesis data) { VisitDate visit = db.visits.Include(v => v.anamnesis).Where(v => v.ID == data.visitID).First(); if (visit == null) return RedirectToAction("Index", "Pacients"); Pacient pacient = db.pacients.Where(p => p.visits.Any(v => v.ID == data.visitID)).First(); if (pacient == null) return RedirectToAction("Index", "Pacients"); if (ModelState.IsValid) { AnamnesisEventType type = db.anamnesisTypes.Where(a => a.ID == data.anamnesis.type.ID).First(); data.anamnesis.type = type; visit.anamnesis.Add(data.anamnesis); db.SaveChanges(); return PartialView("/views/Anamnesis/pacientDetails.cshtml", data.anamnesis); } return PartialView("/views/Anamnesis/pacientCreate.cshtml", data); } 


ふヌ、すべお準備ができたようです。 これらの操䜜は、他のすべおの皮類のドキュメントに察しおのみ実行したす。 ずころで、理論的にはテンプレヌトビュヌを䜜成するなど、これを自動化できたすが、Razorでこれを行うこずはできたせん。 私が間違っおいる堎合は修正したす。

䜜成フォヌムはトリックタブにロヌドされたす

[レセプション]タブのDocumentList.cshtmlビュヌコヌド
 @model WebApplication2.Models.documentList @using WebApplication2.Models @{ var cl = "bs-callout-primary"; var ac = ""; } @if (Model.add == false) { cl = "bs-callout-success"; ac = ""; } <div class="bs-callout @cl"> @if (Model.add == false) { <h5> @Model.visit.date</h5> } else { <h5> </h5> } @if (Model.visit.anamnesis.Count > 0 || Model.add == true) { <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true"> <div class="panel panel-default"> <div class="panel-heading" role="tab" id="@String.Format("#documentHeading{0}", Model.num)" onclick="$('@String.Format("#document{0}", Model.num)').collapse('toogle');"> <h4 class="panel-title"> <a data-toggle="collapse" data-parent="#accordion" href="@String.Format("#document{0}", Model.num)" aria-expanded="true" aria-controls="collapseOne"> <span class="pull-right"><small>@Model.visit.date</small></span> </a> </h4> </div> <div id="@String.Format("document{0}", Model.num)" class="panel-collapse collapse @ac" role="tabpanel" aria-labelledby="headingOne"> <div class="panel-body"> <div id="@String.Format("documentData{0}", Model.num)"> @foreach (var anamnes in Model.visit.anamnesis) { @Html.Partial("~/Views/Anamnesis/pacientDetails.cshtml", anamnes); } </div> @if (Model.add == true) { @Html.Action("pacientCreate", "Anamnesis", new { num = Model.num, visitID = Model.visit.ID}) } </div> </div> </div> </div> Model.num = Model.num + 1; } @if (Model.visit.debutes.Count > 0 || Model.add == true) { <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true"> <div class="panel panel-default"> <div class="panel-heading" role="tab" id="@String.Format("#documentHeading{0}", Model.num)" onclick="$('@String.Format("#document{0}", Model.num)').collapse('toogle');"> <h4 class="panel-title"> <a data-toggle="collapse" data-parent="#accordion" href="@String.Format("#document{0}", Model.num)" aria-expanded="true" aria-controls="collapseOne"> <span class="pull-right"><small>@Model.visit.date</small></span> </a> </h4> </div> <div id="@String.Format("document{0}", Model.num)" class="panel-collapse collapse @ac" role="tabpanel" aria-labelledby="headingOne"> <div class="panel-body"> <div id="@String.Format("documentData{0}", Model.num)"> @foreach (var debut in Model.visit.debutes) { @Html.Partial("~/Views/Debuts/pacientDetails.cshtml", debut); } </div> @if (Model.add == true) { @Html.Action("pacientCreate", "Debuts", new { num = Model.num, visitID = Model.visit.ID }) } </div> </div> </div> </div> Model.num = Model.num + 1; } @if (Model.visit.diagnoses.Count > 0 || Model.add == true) { <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true"> <div class="panel panel-default"> <div class="panel-heading" role="tab" id="@String.Format("#documentHeading{0}", Model.num)" onclick="$('@String.Format("#document{0}", Model.num)').collapse('toogle');"> <h4 class="panel-title"> <a data-toggle="collapse" data-parent="#accordion" href="@String.Format("#document{0}", Model.num)" aria-expanded="true" aria-controls="collapseOne"> <span class="pull-right"><small>@Model.visit.date</small></span> </a> </h4> </div> <div id="@String.Format("document{0}", Model.num)" class="panel-collapse collapse @ac" role="tabpanel" aria-labelledby="headingOne"> <div class="panel-body"> <div id="@String.Format("documentData{0}", Model.num)"> @foreach (var diagnosis in Model.visit.diagnoses) { @Html.Partial("~/Views/Diagnoses/pacientDetails.cshtml", diagnosis); } </div> @if (Model.add == true) { @Html.Action("pacientCreate", "Diagnoses", new { num = Model.num, visitID = Model.visit.ID }) } </div> </div> </div> </div> Model.num = Model.num + 1; } @if (Model.visit.syndromes.Count > 0 || Model.add == true) { <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true"> <div class="panel panel-default"> <div class="panel-heading" role="tab" id="@String.Format("#documentHeading{0}", Model.num)" onclick="$('@String.Format("#document{0}", Model.num)').collapse('toogle');"> <h4 class="panel-title"> <a data-toggle="collapse" data-parent="#accordion" href="@String.Format("#document{0}", Model.num)" aria-expanded="true" aria-controls="collapseOne"> <span class="pull-right"><small>@Model.visit.date</small></span> </a> </h4> </div> <div id="@String.Format("document{0}", Model.num)" class="panel-collapse collapse @ac" role="tabpanel" aria-labelledby="headingOne"> <div class="panel-body"> <div id="@String.Format("documentData{0}", Model.num)"> @foreach (var syndrome in Model.visit.syndromes) { @Html.Partial("~/Views/Syndromes/pacientDetails.cshtml", syndrome); } </div> @if (Model.add == true) { @Html.Action("pacientCreate", "Syndromes", new { num = Model.num, visitID = Model.visit.ID }) } </div> </div> </div> </div> Model.num = Model.num + 1; } @if (Model.visit.researches.Count > 0 || Model.add == true) { <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true"> <div class="panel panel-default"> <div class="panel-heading" role="tab" id="@String.Format("#documentHeading{0}", Model.num)" onclick="$('@String.Format("#document{0}", Model.num)').collapse('toogle');"> <h4 class="panel-title"> <a data-toggle="collapse" data-parent="#accordion" href="@String.Format("#document{0}", Model.num)" aria-expanded="true" aria-controls="collapseOne"> <span class="pull-right"><small>@Model.visit.date</small></span> </a> </h4> </div> <div id="@String.Format("document{0}", Model.num)" class="panel-collapse collapse @ac" role="tabpanel" aria-labelledby="headingOne"> <div class="panel-body"> <div id="@String.Format("documentData{0}", Model.num)"> @foreach (var research in Model.visit.researches) { @Html.Partial("~/Views/Researches/pacientDetails.cshtml", research); } </div> @if (Model.add == true) { @Html.Action("pacientCreate", "Researches", new { num = Model.num, visitID = Model.visit.ID }) } </div> </div> </div> </div> Model.num = Model.num + 1; } @if (Model.visit.assigments.Count > 0 || Model.add == true) { <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true"> <div class="panel panel-default"> <div class="panel-heading" role="tab" id="@String.Format("#documentHeading{0}", Model.num)" onclick="$('@String.Format("#document{0}", Model.num)').collapse('toogle');"> <h4 class="panel-title"> <a data-toggle="collapse" data-parent="#accordion" href="@String.Format("#document{0}", Model.num)" aria-expanded="true" aria-controls="collapseOne"> <span class="pull-right"><small>@Model.visit.date</small></span> </a> </h4> </div> <div id="@String.Format("document{0}", Model.num)" class="panel-collapse collapse @ac" role="tabpanel" aria-labelledby="headingOne"> <div class="panel-body"> <div id="@String.Format("documentData{0}", Model.num)"> @foreach (var assigment in Model.visit.assigments) { @Html.Partial("~/Views/Assigments/pacientDetails.cshtml", assigment); } </div> @if (Model.add == true) { @Html.Action("pacientCreate", "Assigments", new { num = Model.num, visitID = Model.visit.ID }) } </div> </div> </div> </div> Model.num = Model.num + 1; } @if (Model.visit.neurostatuses.Count > 0 || Model.add == true) { <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true"> <div class="panel panel-default"> <div class="panel-heading" role="tab" id="@String.Format("#documentHeading{0}", Model.num)" onclick="$('@String.Format("#document{0}", Model.num)').collapse('toogle');"> <h4 class="panel-title"> <a data-toggle="collapse" data-parent="#accordion" href="@String.Format("#document{0}", Model.num)" aria-expanded="true" aria-controls="collapseOne"> <span class="pull-right"><small>@Model.visit.date</small></span> </a> </h4> </div> <div id="@String.Format("document{0}", Model.num)" class="panel-collapse collapse @ac" role="tabpanel" aria-labelledby="headingOne"> <div class="panel-body"> <div id="@String.Format("documentData{0}", Model.num)"> @foreach (var neurostatus in Model.visit.neurostatuses) { @Html.Partial("~/Views/Neurostatus/pacientDetails.cshtml", neurostatus); } </div> @if (Model.add == true) { @Html.Action("pacientCreate", "Neurostatus", new { num = Model.num, visitID = Model.visit.ID }) } </div> </div> </div> </div> Model.num = Model.num + 1; } @if (Model.visit.reviews.Count > 0 || Model.add == true) { <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true"> <div class="panel panel-default"> <div class="panel-heading" role="tab" id="@String.Format("#documentHeading{0}", Model.num)" onclick="$('@String.Format("#document{0}", Model.num)').collapse('toogle');"> <h4 class="panel-title"> <a data-toggle="collapse" data-parent="#accordion" href="@String.Format("#document{0}", Model.num)" aria-expanded="true" aria-controls="collapseOne"> <span class="pull-right"><small>@Model.visit.date</small></span> </a> </h4> </div> <div id="@String.Format("document{0}", Model.num)" class="panel-collapse collapse @ac" role="tabpanel" aria-labelledby="headingOne"> <div class="panel-body"> <div id="@String.Format("documentData{0}", Model.num)"> @foreach (var review in Model.visit.reviews) { @Html.Partial("~/Views/Reviews/pacientDetails.cshtml", review); } </div> @if (Model.add == true) { @Html.Action("pacientCreate", "Reviews", new { num = Model.num, visitID = Model.visit.ID }) } </div> </div> </div> </div> Model.num = Model.num + 1; } <div class="row"> @Html.ActionLink("     ", "Delete", "VisitDates", new { id = Model.visit.ID }, new { @class = "btn btn-danger btn-sm pull-right", style = "margin-top: 10px;margin-right: 15px;" }) </div> </div> 


ちなみに、圌にずっおは、別のプレれンテヌションも必芁でした。

その結果、次のようになりたした。





サヌバヌに公開


FTP経由でサヌバヌにデプロむするには、プロゞェクトをデプロむし、デヌタベヌスを個別にデプロむする必芁がありたす。これを行うには、プロゞェクトを右クリックしおパブリケヌションを遞択したす。

ダりンロヌドする前に、プロゞェクトのルヌトにあるWeb.Release.Configを線集し、connectionStringを曞き蟌んでサヌバヌ䞊のデヌタベヌスに接続する必芁がありたす。これを行う方法に関する指瀺は、ファむル自䜓にMicrosoftによっお慎重に提䟛されおいたす。

デヌタベヌスの゚クスポヌトは、SQL Server Management Studioを䜿甚しお手動で実行する必芁がありたした。

Azureを䜿甚するず、すべおがさらにシンプルになりたす-スタゞオ自䜓がデヌタベヌスを公開したす。

おわりに


残念ながら、1぀の蚘事ですべおの埮劙な点を説明するこずは非垞に困難ですが、䞀般的なポむントを匷調しようずしたした。プロゞェクトの完党なコヌドはGitHubで提䟛されおいたすhttps://github.com/roctbb/ICNE_EHR/。

いく぀かのこずを正しくしなかったず思いたす。コメントをいただければうれしいです。

䜿甚された゜ヌスは、asp.netずstackoverflow.comの無数の質問でした。

Source: https://habr.com/ru/post/J260867/


All Articles