问题
How could I do the join in linq from the following SQL SELECT statement by using method syntax :
SELECT distinct [LAB_RESULTS].ORDER_ID
,LAB_RESULTS.patient_no
,Patients.PATIENT_NAME
,labtests.TestId
,labtests.TestName
,[RESULT_NUMBER]
,TestsRanges.LowerLimit
,TestsRanges.UpperLimit
,TestsUnits.UnitName
FROM [dbo].[LAB_RESULTS]
inner join LabTests on LabTests.testid=LAB_RESULTS.TESTID
inner join TestsRanges on TestsRanges.TestId = LAB_RESULTS.TESTID
inner join patients on Patients.Patient_No = LAB_RESULTS.patient_no
inner join machines on lab_results.machine_id = machines.machine_id
inner join gender on gender.genderid = Patients.Gender
inner join TestsUnits on TestsUnits.UnitId = LabTests.UnitId
inner join Lab_orders_Cash on Lab_orders_Cash.cash_order_id = LAB_RESULTS.ORDER_ID
inner join PatientCat on (patientcat.CatId = Lab_orders_Cash.CatId)
inner join Lab_Hematology_Samples on Lab_Hematology_Samples.SAMPLE_ID = LAB_RESULTS.SAMPLE_ID
where lab_results.ORDER_ID = 2000000058
and (Lab_orders_Cash.catid = TestsRanges.CatId )
and TestsRanges.machine_id = LAB_RESULTS.machine_id
and (Patients.Gender = TestsRanges.PatientSex or TestsRanges.PatientSex = 1 )
I stated the first part of the controller :
public ActionResult CashData(int id)
{
var tables = new Orders_Tables
{
LabResults = db.LAB_RESULTS.Where(o => o.ORDER_ID == id)
.Include(p => p.LabTests)
.Include(t => t.Patients).ToList(),
LabParaResult = db.LAB_PARA_RESULTS.Where(o => o.ORDER_ID == id).Include(t => t.Patients).ToList(),
LabCultureResults = db.LAB_CULTURE_RESULT.Where(o => o.ORDER_ID == id).ToList(),
LabMicroResults = db.LAB_MICRO_NEGATIVE_RESULT.Where(o => o.ORDER_ID == id).ToList(),
labCashView = db.LAB_RESULT_CASH_VIEW.Where(o => o.order_number == id).ToList(),
labtests = db.LabTests.ToList(),
patients = db.Patients.ToList()
};
}
The important now for me to join TestsRanges , TestsUnits , PatientCat, machines & Gender tables with this part on the controller :
LabResults = db.LAB_RESULTS.Where(o => o.ORDER_ID == id)
.Include(p => p.LabTests)
.Include(t => t.Patients).ToList(),
I created the complete relations in the database and foreign keys :
LabTests table contains Testid as primary key the others tables include testid as foreign key LAB_RESULTS,TestsRanges and TestsUnits
This is class Orders_Tables:
public class Orders_Tables
{
internal IQueryable<object> result { get; set; }
public Lab_Orders LabOrders { get; set; }
public Lab_orders_Cash LabOrdersCash { get; set; }
public Lab_Sample_status LabOrderStatus { get; set; }
public IEnumerable<LAB_RESULTS> LabResults { get; set; }
public IEnumerable<TestsRanges> testsRanges { get; set; }
public IEnumerable<LAB_CULTURE_RESULT> LabCultureResults { get; set; }
public IEnumerable<LAB_MICRO_NEGATIVE_RESULT> LabMicroResults { get; set; }
public IEnumerable<LabTests> labtests { get; set; }
public LAB_RESULTS_CLINIC_VIEW labViewResult { get; set; }
public IEnumerable<LAB_RESULT_CASH_VIEW> labCashView { get; set; }
public IEnumerable<LAB_PARA_RESULTS> LabParaResult { get; set; }
public Lab_Hematology_Samples LabSamples { get; set; }
public IEnumerable<Patients> patients { get; set; }
public IEnumerable<Customers> customers { get; set; }
}
EDIT : I changed the query in controller as the following :
public ActionResult CashData(int id)
{
var tables = new Orders_Tables
{
testsRanges = db.TestsRanges.ToList(),
//LabResults = db.LAB_RESULTS.Where(o => o.ORDER_ID == id )
// .Include(p => p.LabTests)
// .Include(t => t.Patients).ToList(),
//LabResults = result,
result = (from labResult in db.LAB_RESULTS
join labTest in db.LabTests on labResult.TESTID equals labTest.TestId
join testRange in db.TestsRanges on labResult.TESTID equals testRange.TestId
where labResult.ORDER_ID == id
select new { labResult.ORDER_ID, labResult.patient_no, labTest.TestId, labTest.TestName, testRange.LowerLimit, testRange.UpperLimit }).Distinct(),
LabParaResult = db.LAB_PARA_RESULTS.Where(o => o.ORDER_ID == id).Include(t => t.Patients).ToList(),
LabCultureResults = db.LAB_CULTURE_RESULT.Where(o => o.ORDER_ID == id).ToList(),
LabMicroResults = db.LAB_MICRO_NEGATIVE_RESULT.Where(o => o.ORDER_ID == id).ToList(),
labCashView = db.LAB_RESULT_CASH_VIEW.Where(o => o.order_number == id).ToList(),
labtests = db.LabTests.ToList(),
patients = db.Patients.ToList()
};
but how i will call it in view code and foreach loop its not appear ?
this is the view code :
@model AljawdahNewSite.Models.Orders_Tables
@{
ViewBag.Title = "CashData";
Layout = "~/Views/Shared/_LayoutPatients.cshtml";
var hema = new List<int>() { 1 };
var bio = new List<int>() { 2 };
var ser = new List<int>() { 3 };
var hor = new List<int>() { 4 };
var culture = new List<int>() { 7 };
var para = new List<int>() { 6,9 };
var labPara = Model.LabParaResult.FirstOrDefault();
var labCult = Model.LabCultureResults.FirstOrDefault();
var labMicro= Model.LabMicroResults.FirstOrDefault();
var LabResults = Model.LabResults;
var labhema = LabResults.FirstOrDefault(x => x.deptid == 1);
var labBio = LabResults.FirstOrDefault(x => x.deptid == 2);
var labSer = LabResults.FirstOrDefault(x => x.deptid ==3);
var labHor = LabResults.FirstOrDefault(x => x.deptid == 4);
}
@if (labhema != null && labhema.APPROVED_DATE.HasValue)
{
<div class="tab-pane container active" id="hemadiv" >
<h5 class="text-uppercase p-2 text-center">Hematology Department</h5>
<table class="table table-bordered" cellpadding="5" cellspacing="5" border="1">
<thead>
<tr>
<th>@Html.DisplayNameFor(m => m.LabResults.FirstOrDefault().patient_no)</th>
<th>@Html.DisplayNameFor(m => m.patients.FirstOrDefault().Patient_Name)</th>
<th>@Html.DisplayNameFor(m => m.labtests.FirstOrDefault().TestName)</th>
<th>@Html.DisplayNameFor(m => m.LabResults.FirstOrDefault().RESULT_NUMBER)</th>
<th>@Html.DisplayNameFor(m => m.testsRanges.FirstOrDefault().LowerLimit)</th>
<th>@Html.DisplayNameFor(m => m.testsRanges.FirstOrDefault().UpperLimit)</th>
<th>@Html.DisplayNameFor(m => m.testsRanges.FirstOrDefault().text_range)</th>
<th>@Html.DisplayNameFor(m => m.LabResults.FirstOrDefault().APPROVED_DATE)</th>
</tr>
</thead>
@foreach (var employee in Model.LabResults.Where(x => hema.Contains(x.LabTests.Dept_id.GetValueOrDefault())))
{
<tr>
<td>@employee.patient_no</td>
<td>@employee.Patients.Patient_Name</td>
<td>@employee.LabTests.TestName</td>
<td>@employee.RESULT_NUMBER</td>
<td>@employee.result.LowerLimit</td> // how to call here
<td>@employee.result.UpperLimit</td> // how to call here
<td>@employee.result.text_range</td> // how to call here
<td>@employee.APPROVED_DATE</td>
</tr>
}
</table>
</div>
}`
` I tried another way to put the var result outside the var table and assign Labresult = result :
public ActionResult CashData(int id)
{
var result = (from labResult in db.LAB_RESULTS
join labTest in db.LabTests on labResult.TESTID equals labTest.TestId
join testRange in db.TestsRanges on labResult.TESTID equals testRange.TestId
where labResult.ORDER_ID == id
select new { labResult.ORDER_ID, labResult.patient_no, labTest.TestId, labTest.TestName, testRange.LowerLimit, testRange.UpperLimit }).Distinct(),
var tables = new Orders_Tables
{
testsRanges = db.TestsRanges.ToList(),
//LabResults = db.LAB_RESULTS.Where(o => o.ORDER_ID == id )
// .Include(p => p.LabTests)
// .Include(t => t.Patients).ToList(),
//LabResults = result,
LabResults = result,
LabParaResult = db.LAB_PARA_RESULTS.Where(o => o.ORDER_ID == id).Include(t => t.Patients).ToList(),
LabCultureResults = db.LAB_CULTURE_RESULT.Where(o => o.ORDER_ID == id).ToList(),
LabMicroResults = db.LAB_MICRO_NEGATIVE_RESULT.Where(o => o.ORDER_ID == id).ToList(),
labCashView = db.LAB_RESULT_CASH_VIEW.Where(o => o.order_number == id).ToList(),
labtests = db.LabTests.ToList(),
patients = db.Patients.ToList()
};
return View(tables);
}
but it shows error on the row LabResults = result,
Cannot implicitly convert type System.Linq.IQueryable to System Collections.Generic.IEnumerable an explicit conversion exists are you missing a cast ?
Lab Result Class
public partial class LAB_RESULTS
{
public int ID { get; set; }
public int SAMPLE_ID { get; set; }
public int ORDER_ID { get; set; }
public int TESTID { get; set; }
public int GROUPID { get; set; }
public string NORMAL_RESULT { get; set; }
public int SAMPLE_STATUS { get; set; }
public string EXAMINED_BY { get; set; }
public Nullable<System.DateTime> EXAMINED_DATE { get; set; }
public string APPROVED_BY { get; set; }
public Nullable<System.DateTime> APPROVED_DATE { get; set; }
public string RESULT_NUMBER { get; set; }
public string RESULT_REPORT { get; set; }
public string RESULT_NOTE { get; set; }
public Nullable<int> packageid { get; set; }
public Nullable<int> machine_id { get; set; }
public Nullable<int> deptid { get; set; }
public Nullable<int> patient_no { get; set; }
public Nullable<int> custid { get; set; }
public string REQ_FORM_NO { get; set; }
public Nullable<int> serial { get; set; }
public string text { get; set; }
public string value { get; set; }
public string packagename { get; set; }
public string UPDATED_BY { get; set; }
public Nullable<System.DateTime> UPDATED_DATE { get; set; }
public Nullable<int> prio_id { get; set; }
public Nullable<int> update_count { get; set; }
public string REJECTED_BY { get; set; }
public Nullable<System.DateTime> REJECTED_DATE { get; set; }
public Nullable<int> REJECTED_REASON { get; set; }
public virtual LabTests LabTests { get; set; }
public virtual Patients Patients { get; set; }
}
}
Labtest class :
public partial class LabTests
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public LabTests()
{
this.Groups = new HashSet<Groups>();
this.LAB_CULTURE_RESULT = new HashSet<LAB_CULTURE_RESULT>();
this.LAB_HISTO_RESULT = new HashSet<LAB_HISTO_RESULT>();
this.LAB_MICRO_NEGATIVE_RESULT = new HashSet<LAB_MICRO_NEGATIVE_RESULT>();
this.Lab_Packages = new HashSet<Lab_Packages>();
this.LAB_PARA_RESULTS = new HashSet<LAB_PARA_RESULTS>();
this.LAB_RESULTS = new HashSet<LAB_RESULTS>();
this.LAB_SEMEN_ANALYSIS_RESULT = new HashSet<LAB_SEMEN_ANALYSIS_RESULT>();
this.LAB_URINE_ANALYSIS_RESULT = new HashSet<LAB_URINE_ANALYSIS_RESULT>();
this.TestsRanges = new HashSet<TestsRanges>();
}
public int TestId { get; set; }
public string TestName { get; set; }
public Nullable<int> Dept_id { get; set; }
public Nullable<int> Machine_id { get; set; }
public Nullable<int> TestType { get; set; }
public Nullable<int> UnitId { get; set; }
public Nullable<int> TestGender { get; set; }
public Nullable<int> TestAvailable { get; set; }
public Nullable<int> groupid { get; set; }
public Nullable<int> ID_sample { get; set; }
public Nullable<int> test_duration { get; set; }
public string TestNotes { get; set; }
public string group_name { get; set; }
public Nullable<int> culture { get; set; }
public Nullable<int> test_status { get; set; }
public virtual Departments Departments { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Groups> Groups { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<LAB_CULTURE_RESULT> LAB_CULTURE_RESULT { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<LAB_HISTO_RESULT> LAB_HISTO_RESULT { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<LAB_MICRO_NEGATIVE_RESULT> LAB_MICRO_NEGATIVE_RESULT { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Lab_Packages> Lab_Packages { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<LAB_PARA_RESULTS> LAB_PARA_RESULTS { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<LAB_RESULTS> LAB_RESULTS { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<LAB_SEMEN_ANALYSIS_RESULT> LAB_SEMEN_ANALYSIS_RESULT { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<LAB_URINE_ANALYSIS_RESULT> LAB_URINE_ANALYSIS_RESULT { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<TestsRanges> TestsRanges { get; set; }
public virtual TestsUnits TestsUnits { get; set; }
}
}
TestsRanges class
public partial class TestsRanges
{
public Nullable<int> TestId { get; set; }
public Nullable<int> CatId { get; set; }
public Nullable<int> PatientSex { get; set; }
public Nullable<int> CaseId { get; set; }
public string LowerLimit { get; set; }
public string UpperLimit { get; set; }
public int id { get; set; }
public int machine_id { get; set; }
public string text_range { get; set; }
public string panic_value { get; set; }
public virtual LabTests LabTests { get; set; }
}
testid primary key in LabTests table and foreign key in the other tables.
回答1:
To solve such errors and big number of relations just create SQL SERVER VIEW with all relations then add this view to your model view and controllers as one table no need to create any extra join and where and include in your controller just one call:
CREATE VIEW [dbo].[LAB_RESULT_VIEW] AS
SELECT distinct [LAB_RESULTS].ORDER_ID
,LAB_RESULTS.patient_no
,Patients.PATIENT_NAME
,labtests.TestId
,labtests.TestName
,[RESULT_NUMBER]
,TestsRanges.LowerLimit
,TestsRanges.UpperLimit
,TestsUnits.UnitName
FROM [dbo].[LAB_RESULTS]
inner join LabTests on LabTests.testid=LAB_RESULTS.TESTID
inner join TestsRanges on TestsRanges.TestId = LAB_RESULTS.TESTID
inner join patients on Patients.Patient_No = LAB_RESULTS.patient_no
inner join machines on lab_results.machine_id = machines.machine_id
inner join gender on gender.genderid = Patients.Gender
inner join TestsUnits on TestsUnits.UnitId = LabTests.UnitId
inner join Lab_orders_Cash on Lab_orders_Cash.cash_order_id = LAB_RESULTS.ORDER_ID
inner join PatientCat on (patientcat.CatId = Lab_orders_Cash.CatId)
inner join Lab_Hematology_Samples on Lab_Hematology_Samples.SAMPLE_ID = LAB_RESULTS.SAMPLE_ID
where lab_results.ORDER_ID = 2000000058
and (Lab_orders_Cash.catid = TestsRanges.CatId )
and TestsRanges.machine_id = LAB_RESULTS.machine_id
and (Patients.Gender = TestsRanges.PatientSex or TestsRanges.PatientSex = 1 )
来源:https://stackoverflow.com/questions/62204142/translate-sql-server-select-to-linq-with-multiple-join-method-syntax