Trouble understanding LINQ return value - c#

I am trying to return the Actual Value in this query but I only get the Expression. Can someone point me in the right direction please.
public static String NurseName(Guid? userID)
{
var nurseName = from demographic in context.tblDemographics
where demographic.UserID == userID
select new {FullName = demographic.FirstName +" " + demographic.LastName};
String nurseFullName = nurseName.ToString();
return nurseFullName;
}
nurseFullName ends up as --> SELECT ([t0].[FirstName] + #p1) + [t0].[LastName] AS [FullName]
FROM [dbo].[tblDemographics] AS [t0]
WHERE ([t0].[UserID]) = #p0

public static String NurseName(Guid? userID)
{
var nurseName = from demographic in context.tblDemographics
where demographic.UserID == userID
select demographic.FirstName +" " + demographic.LastName;
return nurseName.SingleOrDefault();
}
In the above nurseName has the IQueryable expression, so it hasn't executed anything. Its when you enumerate on it, that the query is called. That's also the case when you call methods like SingleOrDefault.
If you were to use your original query expression instead, you can:
public static String NurseName(Guid? userID)
{
var query= from demographic in context.tblDemographics
where demographic.UserID == userID
select new {FullName = demographic.FirstName +" " + demographic.LastName; }
var nurseName = query.SingleOrDefault();
return nurseName != null ? nurseName.FullName : "";
}
Difference between Single vs. SingleOrDefault is that the later allows an empty result.
Difference between First vs. Single is that the later prevents more than 1 row.

Try this:
var nurseName = (from demographic in context.tblDemographics
where demographic.UserID == userID
select new {FullName = demographic.FirstName +" " + demographic.LastName}).First().FullName;
Your code was grabbing a collection, but not a specific item. This modification takes the first item in the list and returns the FullName property.

public static String NurseName(Guid? userID)
{
var nurseName = (from demographic in context.tblDemographics
where demographic.UserID == userID
select new {FullName = demographic.FirstName +" " + demographic.LastName}).SingleOrDefault();
if(null == nurseName)
{
//TODO: Uh-Oh ID not found...
}
string nurseFullName = nurseName.FullName;
return nurseFullName;
}

Related

How do i filter and search selected fields only and exclude null textboxes in ASP.NET MVC

Simply I have 4 textboxes and I want to search and filter data by one or two or 3 or 4 textboxes and execlude the textbox if i didn't want to search by that textbox :
I am using entityFramework , and I have orders_class include the tables Lab_Orders,Lab_Sample_status,Patients:
The fields I have :
Start Date ---------------
End Date -----------------
Polyclinic File No -------------
ID or Passport No --------------
I select the data depends on the value entered in the textbox fields
I want to search some times the orders between 2 dates (start date to end date) only .
Some times I need to search all orders by patient passport number
some times I need to search by polyclinic File No only
1- I created the View input textboxes :
#using (Html.BeginForm("Clinicsorders", "Orders", FormMethod.Get))
{
<span id="FromDate">From Date</span><input id="FromDatetext" type="text" name="startdate"/>
<span id="ToDate"> To Date</span> <input id="ToFatetext" type="text" name="enddate"/>
<span id="PCfileno">Polyclinic File No</span><input id="pcfilenotext" type="text" name="pcfileno" />
<span id="IDNO">ID/Iqama No</span> <input id="idnotext" type="text" name="idno" />
<br/>
<br/>
<input id="Submit1" type="submit" value="Search Orders" style="margin-left:1000px" />
}
2- I created the controller :
public ActionResult Clinicsorders(DateTime? startdate,DateTime? enddate,string pcfileno,string idno)
{
List<Lab_Orders> Clinicorder = db.Lab_Orders.OrderByDescending(x => x.ORDER_ID).ToList();
List<Lab_Sample_status> samplestatus = db.Lab_Sample_status.ToList();
List<Patients> patients = db.Patients.ToList();
if (startdate == null && enddate == null && pcfileno == null && idno == null)
{
var OrdersList = from o in Clinicorder
join st in samplestatus on o.order_status equals st.status_id
join pt in patients on o.patient_no equals pt.Patient_No
where o.CUSTID == (int)Session["UserCustid"]
select new Orders_Tables { LabOrders = o, LabOrderStatus = st , patients = pt };
return View(OrdersList);
}
else if (startdate != null || enddate != null || pcfileno !=null || idno != null)
{
var OrdersList = from o in Clinicorder
join st in samplestatus on o.order_status equals st.status_id
join pt in patients on o.patient_no equals pt.Patient_No
where o.CUSTID == (int)Session["UserCustid"] && (o.ORDER_DATE >= startdate && o.ORDER_DATE <= enddate)
select new Orders_Tables { LabOrders = o, LabOrderStatus = st , patients = pt };
return View(OrdersList);
}
return View();
}
When I run the view All orders selected by default.
Also I can search and filter now successfully between 2 dates (startdate and enddate).
I want now the remaining parts to filter and search by pcfileno and idno which is string value.
How I will implement this functionality and filter only by and search with the data I need and execlude the null textboxes.
In ASP.NET I implemented this filter before like the following code :
protected void BtnSearch_Click(object sender, EventArgs e)
{
if (Session["custid"] != null && Convert.ToInt32(Session["custid"]) > 0)
{
string sql = #"SELECT [LAB_RESULTS].ORDER_ID as 'order number'
,APPROVED_DATE as 'Report Date'
,labtests.TestId as 'Test Id'
,labtests.TestName as 'Test_Name'
,labtests.culture as 'Culture'
,CASE WHEN coalesce([RESULT_NUMBER],'') <> '' THEN RESULT_NUMBER WHEN coalesce(RESULT_REPORT, '') <> '' THEN RESULT_REPORT END AS Result
,LAB_RESULTS.CUSTID as 'Customer No'
,Customers.CustName as 'Customer Name'
,LAB_RESULTS.patient_no as 'Patient No'
,Patients.PATIENT_NAME as 'Patient Name'
,patientcat.CatName as 'Category'
,Patients.Age AS 'AGE'
,gender.gendername as 'SEX'
,LAB_RESULTS.deptid AS 'DEPTID'
,TestsRanges.LowerLimit as 'Low Range'
,TestsRanges.UpperLimit as 'High Range'
,TestsRanges.text_range as 'Text Range'
,Lab_Hematology_Samples.COLLECTION_DATE as 'Collection Date'
,LAB_RESULTS.REQ_FORM_NO as 'REQ FORM NUMBER'
FROM [dbo].[LAB_RESULTS]
inner join LabTests on LabTests.testid=LAB_RESULTS.TESTID
inner join TestsRanges on TestsRanges.TestId = LAB_RESULTS.TESTID
inner join PatientCat on patientcat.CatId = TestsRanges.CatId
inner join Customers on Customers.CustId=LAB_RESULTS.CUSTID
inner join patients on Patients.Patient_No = LAB_RESULTS.patient_no
inner join gender on gender.genderid = Patients.Gender
inner join Lab_Orders on Lab_Orders.ORDER_ID = LAB_RESULTS.ORDER_ID
inner join Lab_Hematology_Samples on Lab_Hematology_Samples.ORDER_ID = LAB_RESULTS.ORDER_ID
where lab_results.deptid =1
and (Lab_Orders.catid = TestsRanges.CatId or PatientCat.CatId =5)
and LAB_RESULTS.EXAMINED_DATE is not null
and LAB_RESULTS.APPROVED_DATE is not null
and LAB_RESULTS.update_count in (select max(update_count) from LAB_RESULTS A where A.SAMPLE_STATUS = 6 and A.deptid=LAB_RESULTS.DEPTID and A.ORDER_ID = LAB_RESULTS.ORDER_ID)
and (Patients.Gender = TestsRanges.PatientSex or TestsRanges.PatientSex = 1 )
AND TestsRanges.machine_id = LAB_RESULTS.machine_id ";
string condition = "";
string orderby = "";
condition += " and LAB_RESULTS.custid ='" + Session["custid"] + "'";
orderby += "order by LAB_RESULTS.ORDER_ID desc";
if (DropDownTest.SelectedValue != "")
{
condition += " and labtests.TestId ='" + DropDownTest.SelectedValue + "'";
}
if (TxtPatientNo.Text != "")
{
condition += " and LAB_RESULTS.patient_no='" + TxtPatientNo.Text + "'";
}
if (txtreq.Text != "")
{
condition += " and LAB_RESULTS.REQ_FORM_NO='" + txtreq.Text + "'";
}
if (TxtFromDate.Text != "")
{
string date_day = Convert.ToDateTime(TxtFromDate.Text).Day.ToString();
string date_month = Convert.ToDateTime(TxtFromDate.Text).Month.ToString();
string date_year = Convert.ToDateTime(TxtFromDate.Text).Year.ToString();
string date = date_month + "/" + date_day + "/" + date_year;
condition += " and Lab_Hematology_Samples.COLLECTION_DATE > '" + date + "'";
}
if (TxtToDate.Text != "")
{
string date_day = Convert.ToDateTime(TxtToDate.Text).Day.ToString();
string date_month = Convert.ToDateTime(TxtToDate.Text).Month.ToString();
string date_year = Convert.ToDateTime(TxtToDate.Text).Year.ToString();
string date = date_month + "/" + date_day + "/" + date_year;
condition += " and Lab_Hematology_Samples.COLLECTION_DATE < '" + date + "'";
}
DataTable dt = func.fireDatatable(string.Format(sql + condition + orderby));
GridView1.DataSource = dt;
GridView1.DataBind();
}
How i will make same functionality in MVC and linq
If pcfileno textbox != null then search
if idno textbox != null then search ??
Assuming you are using EntityFramework and LazyLoading is disabled and your entities have navigation properties Lab_Sample_Status and Patient, you can utilize the IQueryable like the ff:
int custId = (int)Session["UserCustid"];
// eager load navigation properties
// query is IQueryable
var query = db.Lab_Orders.Include("Lab_Sample_Status").Include("Patient").Where(r => r.CUSTID == custId);
if (startdate.HasValue && enddate.HasValue)
{
query = query.Where(r => DbFunctions.TruncateTime(r.Lab_Sample_Status.CollectionDate) >= DbFunctions.TruncateTime(startdate.Value) &&
DbFunctions.TruncateTime(r.Lab_Sample_Status.CollectionDate) <= DbFunctions.TruncateTime(enddate.Value));
}
if (!string.IsNullOrEmpty(pcfileno))
{
query = query.Where(r => r.Lab_Sample_Status.PcFileNo == pcfileno);
}
if (!string.IsNullOrEmpty(idno))
{
query = query.Where(r => r.Patient.PatientNo == idno);
}
// .. You can continue to manipulate the query
// db results is determined upon calling ToList()
var model = query.ToList().Select(r => new Orders_Tables() { LabOrders = r, LabOrderStatus = r.Lab_Sample_Status, Patient = r.Patient });
return View(model);
If you don't have navigation properties like indicated above, you can do the ff:
int custId = (int)Session["UserCustid"];
// query is IQueryable
var query = db.Lab_Orders.Where(r => r.CUSTID == custId)
.Join(db.Lab_Sample_Status, order => order.order_status, status => status.status_id, (order, status) => new { Order = order, Status = status })
.Join(db.Patients, rec => rec.Order.patient_no, patient => patient.Patient_No, (rec, patient) => new Orders_Tables { LabOrders = rec.Order, LabOrderStatus = rec.Status, patients = patient });
if (startdate.HasValue && enddate.HasValue)
{
query = query.Where(r => DbFunctions.TruncateTime(r.LabOrderStatus.CollectionDate) >= DbFunctions.TruncateTime(startdate.Value) &&
DbFunctions.TruncateTime(r.LabOrderStatus.CollectionDate) <= DbFunctions.TruncateTime(enddate.Value));
}
if (!string.IsNullOrEmpty(pcfileno))
{
query = query.Where(r => r.LabOrderStatus.PcFileNo == pcfileno);
}
if (!string.IsNullOrEmpty(idno))
{
query = query.Where(r => r.patients.Patient_No == idno);
}
// db results is determined upon calling ToList()
var model = query.ToList();
return View(model);
PS: I'm hesitant to post this as an answer since OP's question isn't clear enough but the comment section has gotten a bit long.

Linq To SQL toList<class> - Invalid Cast

I am not sure what I am doing wrong. But the linq to sql is choking when I do a toList.
it is running this area of the select.
case RightSearchType.Text:
If put the results in a var variable and not use the ToList it runs fine gets the results no problem.
I have tried
ToList()
ToList<URRightsView>()
Both of them yield the same issue.
I wish to pass back a strongly type List when developers call this method.
Please keep in mind this is not finished code. This is the first time I am using LINQ to SQL and my very first test to see if I am doing it right.
Thus failing badly.
Any help in resolving the casting problem is truly appreciated :)
public static List<URRightsView> Search(string SearchText, long Id, RightSearchType SearchType)
{
List<URRightsView> dRights = null;
try
{
using (DataContext db = new DataContext(AppSettings.Settings.ConnectionString))
{
Table<URRights> tRights = db.GetTable<URRights>();
Table<URRoles> tRoles = db.GetTable<URRoles>();
Table<URApps> tApps = db.GetTable<URApps>();
Table<URRightRoleMapping> tMapRoles = db.GetTable<URRightRoleMapping>();
Table<URApplicationRight> tMapApps = db.GetTable<URApplicationRight>();
string results = string.Empty;
switch (SearchType) {
case RightSearchType.Application:
dRights = (from ma in tMapApps
join apps in tApps on ma.AppFK equals apps.AppId
join r in tRights on ma.RightFK equals r.RightId
where (r.Title.Contains(SearchText) || r.Description.Contains(SearchText)) && ma.AppFK == Id
orderby r.Title, apps.Name ascending
select new URRightsView
{
Title = r.Title,
Classification = r.Classification,
Description = r.Description,
RightId = URUtil.GetLong(r.RightId),
RightType = r.RightType,
AppName = apps.Name
}).ToList<URRightsView>();
break;
case RightSearchType.Role:
dRights = (from ma in tMapApps
join apps in tApps on ma.AppFK equals apps.AppId
join r in tRights on ma.RightFK equals r.RightId
join mr in tMapRoles on r.RightId equals mr.RightFK
where (r.Title.Contains(SearchText) || r.Description.Contains(SearchText)) && ma.AppFK == Id
orderby r.Title, apps.Name ascending
select new URRightsView
{
Title = r.Title,
Classification = r.Classification,
Description = r.Description,
RightId = URUtil.GetLong(r.RightId),
RightType = r.RightType,
AppName = apps.Name
}).ToList<URRightsView>();
break;
case RightSearchType.Text:
dRights = (from ma in tMapApps
join apps in tApps on ma.AppFK equals apps.AppId
join r in tRights on ma.RightFK equals r.RightId
where r.Title.Contains(SearchText) || r.Description.Contains(SearchText)
orderby r.Title, apps.Name ascending
select new URRightsView
{
Title = URUtil.GetString(r.Title),
Classification = URUtil.GetString(r.Classification),
Description = URUtil.GetString(r.Description),
RightId = URUtil.GetLong(r.RightId),
RightType = URUtil.GetLong(r.RightType),
AppName = URUtil.GetString(apps.Name)
}).ToList<URRightsView>();
break;
}
}
}
catch (Exception ex)
{
URErrors.HandleError(ex, UserName);
JavaScriptSerializer serial = new JavaScriptSerializer();
string error = "URRights.Search Method: Could not Search Text - " + SearchText + ", SearchType = " + SearchType.ToString() + ",Id = " + Id.ToString() + Environment.NewLine;
URErrors.HandleError(ex, UserName);
throw new Exception(error);
}
return dRights;
}
UPDATE WITH EXCEPTION
Message
Specified cast is not valid.
at System.Data.SqlClient.SqlBuffer.get_Int64()
at System.Data.SqlClient.SqlDataReader.GetInt64(Int32 i)
at Read_URRightsView(ObjectMaterializer`1 )
at System.Data.Linq.SqlClient.ObjectReaderCompiler.ObjectReader`2.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at URCore.URSecurity.URRights.Search(String SearchText, Int64 Id, RightSearchType SearchType) in D:\Development\Websites\unravelingspirit\URCore\URSecuirty\URRights.cs:line 244

One context reference LINQ query throws multiple references exception - BUG?

I'm using the following code:
using(MainEntities mainContext = new MainEntities())
{
return (from member in mainContext.aspnet_Membership
where adminGroupUserIDs.Contains(member.UserId)
select new
{
FullName = member.FirstName + " " + member.LastName,
UserName = (from user in mainContext.aspnet_Users
where user.UserId == member.UserId
select user.UserName)
}).ToList();
}
where adminGroupUserIDs is an IQueryable<GUID> that is formed from a query to a different instance of MainEntities.
With this query LINQ complains that:
The specified LINQ expression contains references to queries that are associated with different contexts.
Any ideas why?
I can't be certain from the code you show here, but I'm pretty sure that adminGroupUserIDs is the result of another query that hasn't been retrieved yet, and was created with a different instance of MainEntities. You can't mix queries from different contexts, not even different instances of the same context class. Try changing it to the following:
var loadedAdminGroupUserIDs = adminGroupUserID.ToArray();
using(MainEntities mainContext = new MainEntities())
{
return (from member in mainContext.aspnet_Membership
where loadedAdminGroupUserIDs.Contains(member.UserId)
select new
{
FullName = member.FirstName + " " + member.LastName,
UserName = (from user in mainContext.aspnet_Users
where user.UserId == member.UserId
select user.UserName)
}).ToList();
}
Try adding .FirstOrDefault() to your subquery.
using(MainEntities mainContext = new MainEntities())
{
return (from member in mainContext.aspnet_Membership
where adminGroupUserIDs.Contains(member.UserId)
select new
{
FullName = member.FirstName + " " + member.LastName,
UserName = (from user in mainContext.aspnet_Users
where user.UserId == member.UserId
select user.UserName).FirstOrDefault()
}).ToList();
}

return one string with multiple column value linq

I have a query.
Is it possible to return One string with multiple column value in linq ??
Like this
string ProductName = ((from P in DataModel.DIS_PRODUCT
join M in DataModel.SET_PACK_UNIT on P.PUNIT_ID equals M.ID
where P.PRODUCT_ID == ProdictId
select P.PRODUCT_NAME +" " + P.WEIGHT + " "+ M.UNIT_SYMBLE)
.Take(1)
).ToString();
You're using Take(1) which means you're still getting an IEnumerable<string> or an IQueryable<string>. Just use First() (or possibly FirstOrDefault()) instead of Take(1) and you can drop the ToString() call as well.
string productName = (from P in DataModel.DIS_PRODUCT
join M in DataModel.SET_PACK_UNIT
on P.PUNIT_ID equals M.ID
where P.PRODUCT_ID == ProdictId
select P.PRODUCT_NAME + " " + P.WEIGHT + " "+ M.UNIT_SYMBLE)
.FirstOrDefault();
That will only work if your LINQ provider supports the string concatenation operation. An alternative is to fetch just the columns you want, and then concatenate at the caller:
var query = from P in DataModel.DIS_PRODUCT
join M in DataModel.SET_PACK_UNIT
on P.PUNIT_ID equals M.ID
where P.PRODUCT_ID == ProdictId
select new { P.PRODUCT_NAME, P.WEIGHT, M.UNIT_SYMBLE };
var result = query.FirstOrDefault();
if (result != null)
{
string productName = result.PRODUCT_NAME + " " +
result.WEIGHT + " " +
result.UNIT_SYMBLE;
// Use the name
}
else
{
// No results
}
Another more clear way is the following
var ProductsQueryItem = (from p in Products
select new
{
Name = e.ProductName+ " " + e.weight +e.UNIT_SYMBLE
})
.FirstOrDefault();
Now you can use it directly with ProductsQueryItem .Name

Nested LINQ Method throwing a `Not Supported...` Exception

This is a follow up from here -->multiple-sorting-on-linq-nested-method .
Basically, on let memberName = ... it is throwing this exception Method 'System.String MemberName(Int32)' has no supported translation to SQL. and I am not figuring out the solution.
Also, BLLCmo and BLLConnect actually use TWO different DataBases. The original app(not mine) uses 4 Seperate DB's so I am trying to make due.
BLLCmo.cs
public static DataTable GetAllMembers(Guid workerID)
{
var AllEnrollees = from enrollment in context.tblCMOEnrollments
where enrollment.CMOSocialWorkerID == workerID || enrollment.CMONurseID == workerID
join supportWorker in context.tblSupportWorkers on enrollment.EconomicSupportWorkerID equals supportWorker.SupportWorkerID into workerGroup
from worker in workerGroup.DefaultIfEmpty()
let memberName = BLLConnect.MemberName(enrollment.ClientID)
orderby enrollment.DisenrollmentDate ascending, memberName ascending
select new
{
enrollment.ClientID,
MemberName = memberName,
NurseName = BLLAspnetdb.NurseName(enrollment.CMONurseID),
SocialWorkerName =BLLAspnetdb.SocialWorkerName(enrollment.CMOSocialWorkerID),
enrollment.DisenrollmentDate,
enrollment.EnrollmentDate,
ESFirstName = worker.FirstName,
ESLastName = worker.LastName,
ESPhone = worker.Phone
};
var dataTable = AllEnrollees.CopyLinqToDataTable();
return dataTable;
}
BLLConnect.cs
public static String MemberName(Int32 personID)
{
var memberName = from person in context.tblPersons
where person.PersonID == personID
select person.FirstName + " " + person.LastName;
return memberName.SingleOrDefault();
}
The problem is that LINQ to SQL is trying to translate your method into SQL. Since MemberName isn't valid SQL, it gives up. Instead, you'll need to pull down the data you need from SQL and then call your methods (and sort) in a separate LINQ to Objects query:
public static DataTable GetAllMembers(Guid workerID)
{
var AllEnrollees =
from enrollment in context.tblCMOEnrollments
where enrollment.CMOSocialWorkerID == workerID || enrollment.CMONurseID == workerID
join supportWorker in context.tblSupportWorkers on enrollment.EconomicSupportWorkerID equals supportWorker.SupportWorkerID into workerGroup
from worker in workerGroup.DefaultIfEmpty()
select new
{
enrollment.ClientID,
enrollment.CMONurseID,
enrollment.CMOSocialWorkerID,
enrollment.DisenrollmentDate,
enrollment.EnrollmentDate,
ESFirstName = worker.FirstName,
ESLastName = worker.LastName,
ESPhone = worker.Phone
};
var result =
from enrollee in AllEnrollees.AsEnumerable()
let memberName = BLLConnect.MemberName(enrollee.ClientID)
orderby enrollee.DisenrollmentDate ascending, memberName ascending
select new
{
enrollee.ClientID,
MemberName = memberName,
NurseName = BLLAspnetdb.NurseName(enrollee.CMONurseID),
SocialWorkerName = BLLAspnetdb.SocialWorkerName(enrollee.CMOSocialWorkerID),
enrollee.DisenrollmentDate,
enrollee.EnrollmentDate,
enrollee.ESFirstName,
enrollee.ESLastName,
enrollee.ESPhone
};
return result.CopyLinqToDataTable();
}

Categories