How to get the count of values in table using linq - c#

im required to make a query to db to fetch data fro a highchart widget in our site here is the code I use currently,
var highChartsData =
(from a in db.roomdetails
join b in db.ApplySchedule on a.RoomId equals b.RoomID
where b.Status == true
select new HighlinePie
{
Title = a.RoomName,
Date = b.MDate,
Value = db.ApplySchedule.Where(x => x.RoomID == a.RoomId).GroupBy(x=>x.MDate).Count(),
}).ToList();
The problem with this approach is right now get the total count but what i need is the count based on date, for example if there was two entry on date 12/09/20201 and three entry on 14/09/20201 the data should be "Title,12/09/20201,2","Title,14/09/20201,3".

You have to use grouping:
var groupQuery =
from a in db.roomdetails
join b in db.ApplySchedule on a.RoomId equals b.RoomID
where b.Status == true
group b by new { a.RoomName, b.MDate } into g
select new HighlinePie
{
Title = g.Key.RoomName,
Date = g.Key.MDate,
Value = g.Count()
};
var highChartsData = groupQuery.ToList();

Related

how do i ignore tables with no rows and return values from other tables in linq

I'm working on this conference app where I have to return certain values from the different table using join queries using LINQ
from a in db.ApplySchedule
join b in db.userdetails on a.UserID equals b.UserId
join c in db.roomdetails on a.RoomID equals c.RoomId
join d in db.VideoFiles on a.RoomID equals d.RoomId where d.IsActive == true || d.IsActive==false
join e in db.ImageFiles on a.RoomID equals e.RoomId where e.IsActive == true|| e.IsActive==false
where EntityFunctions.TruncateTime(a.MDate) == EntityFunctions.TruncateTime(DateTime.Now) && a.RoomID == id
&& a.Status == true
select new ShedulerViewModel
{
Id = a.BookingID,
UserId = a.UserID,
Uname = b.UserName,
RoomId = a.RoomID,
Rname = c.RoomName.ToUpper(),
Organizer = a.SubjectDetail,
Date = a.MDate,
FromTime = a.start_date,
ToTime = a.end_date,
//Accesseries = a.Accesseries,
attend = a.Attend,
VideoID = d.RoomId,
VideoPath = d.FilePath,
videoIsActive= d.IsActive,
ImageId = e.RoomId,
ImagePath = e.FilePath,
ImageIsActive = e.IsActive
};
Here is the problem, I'm able to get the values if the last two tables db.imagefiles and db.videofiles has matching values but incase it doesn't I'm getting 0 value from all the other tables even though there are rows with matching id, how do I overcome this? I want to pass value even if the video and image tables have no rows.

How to do concat or group by in linq? I am getting multiples values want to concat the data by ','

my Query:
var s = entities.Doctors.SingleOrDefault(x => x.AreaId == id);
var z = (from x in entities.Doctors
join y in entities.Areas on x.AreaId equals y.AreaId
join s1 in entities.Availabilties on s.D_Id equals s1.DoctorId
join s2 in entities.Eductions on s.D_Id equals s2.DoctorId
join s3 in entities.DoctorSpecialities on s.D_Id equals s3.DoctorId
join s4 in entities.Specialities on s3.SpecialityId equals s4.SpecialityId
join s5 in entities.DaysDetails on s1.DaysId equals s5.DaysId
join s6 in entities.Degrees on s2.DegreeId equals s6.DegreeId
where x.AreaId.Equals(id)
select new DoctorDisplay
{
D_name = x.D_Name,
D_address = x.D_Address,
D_Area = y.AreaName,
D_Contact1 = x.D_Contactone,
D_Contact2 = x.D_Contacttwo,
D_fax = x.D_Faxno,
D_SpecialityName = s4.SpecialityName,
D_Availstarttime = s1.StartTime,
D_Availlasttime = s1.LastTime,
D_Availday= s5.DaysName,
D_DegreeName = s6.DegreeName,
D_Awards = x.D_Address,
D_Status = x.D_Status
}).ToList();
****Getting Output****
[{"D_name":"Shanu","D_address":"block123","D_Area":"Manama","D_Contact1":"123","D_Contact2":"456","D_fax":"789","D_SpecialityName":"Dietician","D_Availstarttime":"9PM","D_Availlasttime":"11PM","D_Availday":"Sunday","D_DegreeName":"MBBS","D_Awards":"block123","D_Status":"Available"},{"D_name":"Shanu","D_address":"block123","D_Area":"Manama","D_Contact1":"123","D_Contact2":"456","D_fax":"789","D_SpecialityName":"Dietician","D_Availstarttime":"9PM","D_Availlasttime":"11PM","D_Availday":"Sunday","D_DegreeName":"Dentistdegree","D_Awards":"block123","D_Status":"Available"},{"D_name":"Shanu","D_address":"block123","D_Area":"Manama","D_Contact1":"123","D_Contact2":"456","D_fax":"789","D_SpecialityName":"Ayurveda","D_Availstarttime":"9PM","D_Availlasttime":"11PM","D_Availday":"Sunday","D_DegreeName":"MBBS","D_Awards":"block123","D_Status":"Available"},{"D_name":"Shanu","D_address":"block123","D_Area":"Manama","D_Contact1":"123","D_Contact2":"456","D_fax":"789","D_SpecialityName":"Ayurveda","D_Availstarttime":"9PM","D_Availlasttime":"11PM","D_Availday":"Sunday","D_DegreeName":"Dentistdegree","D_Awards":"block123","D_Status":"Available"},{"D_name":"Shanu","D_address":"block123","D_Area":"Manama","D_Contact1":"123","D_Contact2":"456","D_fax":"789","D_SpecialityName":"Dietician","D_Availstarttime":"4AM","D_Availlasttime":"11AM","D_Availday":"Monday","D_DegreeName":"MBBS","D_Awards":"block123","D_Status":"Available"},{"D_name":"Shanu","D_address":"block123","D_Area":"Manama","D_Contact1":"123","D_Contact2":"456","D_fax":"789","D_SpecialityName":"Dietician","D_Availstarttime":"4AM","D_Availlasttime":"11AM","D_Availday":"Monday","D_DegreeName":"Dentistdegree","D_Awards":"block123","D_Status":"Available"},{"D_name":"Shanu","D_address":"block123","D_Area":"Manama","D_Contact1":"123","D_Contact2":"456","D_fax":"789","D_SpecialityName":"Ayurveda","D_Availstarttime":"4AM","D_Availlasttime":"11AM","D_Availday":"Monday","D_DegreeName":"MBBS","D_Awards":"block123","D_Status":"Available"},{"D_name":"Shanu","D_address":"block123","D_Area":"Manama","D_Contact1":"123","D_Contact2":"456","D_fax":"789","D_SpecialityName":"Ayurveda","D_Availstarttime":"4AM","D_Availlasttime":"11AM","D_Availday":"Monday","D_DegreeName":"Dentistdegree","D_Awards":"block123","D_Status":"Available"}]
Group_concat on the basis of Education Id, DoctorspecialitiesID, Avaibilities Id,
Image of Input and desire Output
Looking at you example output, it looks less like you want to "concat the data by ','" as much as you want to convert it to JSON.
Inwhichcase, you'd probably be better off using a tool like Newtonsoft's JSON.NET
UPDATE (based on comments):
Assume doctors is the result of the query given in question.
var output =
from d in doctors
group d by new { d.D_NAME, d.D_Area } into dg
select new DoctorDisplay
{
D_NAME = dg.Key.D_NAME,
D_Area = dg.Key.D_Area,
D_SpecialityName = String.Join(",", dg.Select(d => d.D_SpecialityName).Distinct()),
D_DegreeName = String.Join(",", dg.Select(d => d.D_DegreeName).Distinct())
};

c# Linq query with Tuple List [duplicate]

This question already has answers here:
Create a Tuple in a Linq Select
(6 answers)
Closed 6 years ago.
I have 2 database tables.
In Table1 Calculate I have 1 row which is mapped via an Id to multiple rows in table2 CalculdateData.
Now I need to load the data from table1 Calculate with all relevant Details from Table2 CalculdateData.
How would i have the Details into a Tuple-List.?
So basically for CalculateData I have 4 columns per row which I Need to put into a Tuple. Meaning if I would have for example 4 rows i need to create 4 Tuples in a List.
IEnumerable<Storage> context = new MyEntities();
var Result = (from a in context.calculate
join b in context.CalculateData on a.Id equals b.CalcId into c
where a.SpecialID == 2023 && a.VersionId == 1
orderby a.InternalOrderNr ascending
select new Storage
{
myField1 = a.Field1;
myField2 = a.Field2;
myField3 = a.Field3;
< MISSING PART AND QUESTION >
}).ToList();
return Result;
public class Storage
{
public int myField1;
public int myField2;
public int myField3;
public List<Tuple<int, int, string, decimal>> myField4;
}
This should work:
var Result = (from a in calculate
join b in calculateData on a.Id equals b.CalcId into c
where a.SpecialID == 2023 && a.VersionId == 1
orderby a.InternalOrderNr ascending
select new Storage
{
myField1 = a.Field1,
myField2 = a.Field2,
myField3 = a.Field3,
myField4 = c.Select(d => new Tuple<int, int, string, decimal>
(d.Field1, d.Field2, d.Field3, d.Field4))
.ToList()
}).ToList();
return Result;
It also would be good thing to check that this query transforms in single sql request and you not making new sql request on each tuple list creation.
Edit: In case you will have problems with custom types in query (as #Toxantron pointed) this selection should work:
var queryResult = (from a in calculate
join b in calculateData on a.Id equals b.CalcId into c
where a.SpecialID == 2023 && a.VersionId == 1
orderby a.InternalOrderNr ascending
select new
{
a.Field1,
a.Field2,
a.Field3,
myField4 = c.Select(d => new {
d.Field1, d.Field2, d.Field3, d.Field4})
}).ToList();
result = queryResult.Select(r => new Storage
{
myField1 = r.Field1,
myField2 = r.Field2,
myField3 = r.Field3,
myField4 = r.myField4.Select(t => new Tuple<int,int,decimal,string>
(t.Field1, t.Field2, t.Field3, t.Field4))
.ToList()
})
return Result;
You could try something like this.This is not tested yet.
select new Storage
{
myField1 = a.Field1,
myField2 = a.Field2,
myField3 = a.Field3,
myField4 = c.Select(d => new Tuple<int, int, string, decimal>(d.Field1, d.Field2, d.Field3, d.Field4)).ToList()
}).ToList();
This is totally based on this This tutorial

Linq to select data from one table not in other table

Hi i have the following code to select data from one table not in other table
var result1 = (from e in db.Users
select e).ToList();
var result2 = (from e in db.Fi
select e).ToList();
List<string> listString = (from e in result1
where !(from m in result2
select m.UserID).Contains(e.UserID)
select e.UserName).ToList();
ViewBag.ddlUserId = listString;
Am getting value inside listString .But got error while adding listString to viewbag.
Unable to cast object of type 'System.Collections.Generic.List`1[System.String]' to type 'System.Collections.Generic.IEnumerable`1[Main.Models.Admin.User]'.
First, could you update your question with the entire method so that we can see what might be going on with the ViewBag? Because your code should work just fine, assigning whatever value to the ViewBag is no problem normally:
ViewBag.property1 = 0;
ViewBag.property1 = "zero";
works just fine. ViewBag is dynamic. Now, you could get that error if you would later try to assing ViewBag.ddlUserId to something that actually is the wrong type.
I would like you to rewrite your statement as well, let me explain why. Assume for a moment that you have a lot ( > 100.000) of User records in your db.Users and we assume the same for Fi as well. In your code, result1 and result2 are now two lists, one containing >100.000 User objects and the other >100.000 Fi objects. Then these two lists are compared to each other to produce a list of strings. Now imagine the resource required for your web server to process this. Under the assumption that your actually using/accessing a separate SQL server to retrieve your data from, it would be a lot better and faster to let that server do the work, i.e. producing the list of UserID's.
For that you'd either use Kirill Bestemyanov's answer or the following:
var list = (from user in db.Users
where !db.Fi.Any(f => f.UserID == user.UserID)
select user.UserName).ToList()
This will produce just one query for the SQL server to execute:
SELECT
[Extent1].[UserName] AS [UserName]
FROM [dbo].[Users] AS [Extent1]
WHERE NOT EXISTS (SELECT
1 AS [C1]
FROM [dbo].[Fi] AS [Extent2]
WHERE [Extent2].[UserID] = [Extent1].[UserID]
)}
which in the end is what you want...
Just to clarify more:
var list = (from user in db.Users
where !db.Fi.Any(f => f.UserID == user.UserID)
select user.UserName).ToList()
can be written as the following lambda expression as well:
var list = db.Users.Where(user => !db.Fi.Any(f => f.UserID == user.UserID))
.Select(user => user.UserName).ToList()
which from the looks of it is slightly different from Kirill Bestemyanov's answer (which I slightly modified, just to make it look more similar):
var list = db.Users.Where(user => !db.Fi.Select(f => f.UserID)
.Contains(user.UserID))
.Select(user => user.UserName).ToList();
But, they will in fact produce the same SQL Statement, thus the same list.
I will rewrite it to linq extension methods:
List<string> listString = db.Users.Where(e=>!db.Fi.Select(m=>m.UserID)
.Contains(e.UserID))
.Select(e=>e.UserName).ToList();
try it, it should work.
Try this it is very simple.
var result=(from e in db.Users
select e.UserID).Except(from m in db.Fi
select m.UserID).ToList();
var res = db.tbl_Ware.where(a => a.tbl_Buy.Where(c => c.tbl_Ware.Title.Contains(mtrTxtWareTitle.Text)).Select(b => b.Ware_ID).Contains(a.ID));
This mean in T-SQL is:
SELECT * FROM tbl_Ware WHERE id IN (SELECT ware_ID, tbl_Buy WHErE tbl_Ware.title LIKE '% mtrTxtwareTitle.Text %')
getdata = (from obj in db.TblManageBranches
join objcountr in db.TblManageCountries on obj.Country equals objcountr.iCountryId.ToString() into objcount
from objcountry in objcount.DefaultIfEmpty()
where obj.IsActive == true
select new BranchDetails
{
iBranchId = obj.iBranchId,
vBranchName = obj.vBranchName,
Addressline1 = obj.Addressline1,
Adminemailid = obj.Adminemailid,
BranchType = obj.BranchType,
Country = objcountry.vCountryName,
CreatedBy = obj.CreatedBy,
CreatedDate = obj.CreatedDate,
iArea = obj.iArea,
iCity = obj.iCity,
Infoemailid = obj.Infoemailid,
Landlineno = obj.Landlineno,
Mobileno = obj.Mobileno,
iState = obj.iState,
Pincode = obj.Pincode,
Processemailid = obj.Processemailid,
objbranchbankdetails = (from objb in db.TblBranchesBankDetails.Where(x => x.IsActive == true && x.iBranchId == obj.iBranchId)
select new ManageBranchBankDetails
{
iBranchId = objb.iBranchId,
iAccountName = objb.iAccountName,
iAccountNo = objb.iAccountNo,
iBankName = objb.iBankName,
iAccountType = objb.iAccountType,
IFSCCode = objb.IFSCCode,
SWIFTCode = objb.SWIFTCode,
CreatedDate = objb.CreatedDate,
Id = objb.Id
}).FirstOrDefault(),
objbranchcontactperson = (from objc in db.tblbranchcontactpersons.Where(x => x.Isactive == true && x.branchid == obj.iBranchId)
select new ManageBranchContactPerson
{
branchid = objc.branchid,
createdate = objc.createdate,
Id = objc.Id,
iemailid = objc.iemailid,
ifirstname = objc.ifirstname,
ilandlineno = objc.ilandlineno,
ilastname = objc.ilastname,
imobileno = objc.imobileno,
title = objc.title,
updateddate=objc.updateddate,
}).ToList(),
}).OrderByDescending(x => x.iBranchId).ToList();
getdata = (from obj in db.TblManageBranches join objcountr in db.TblManageCountries on obj.Country equals objcountr.iCountryId.ToString() into objcount from objcountry in objcount.DefaultIfEmpty() where obj.IsActive == true
select new BranchDetails
{
iBranchId = obj.iBranchId,
vBranchName = obj.vBranchName,
objbranchbankdetails = (from objb in db.TblBranchesBankDetails.Where(x => x.IsActive == true && x.iBranchId == obj.iBranchId)
select new ManageBranchBankDetails
{
iBranchId = objb.iBranchId,
iAccountName = objb.iAccountName,
}).FirstOrDefault(),
objbranchcontactperson = (from objc in db.tblbranchcontactpersons.Where(x => x.Isactive == true && x.branchid == obj.iBranchId)
select new ManageBranchContactPerson
{
branchid = objc.branchid,
createdate = objc.createdate,
Id = objc.Id,
iemailid = objc.iemailid,
}).ToList(),
}).OrderByDescending(x => x.iBranchId).ToList();

Grouping troubles

Hi i am having difficulties to group these data as it has no aggregate function. I have the following data in 2 tables and i would like to Join both by PaymentId and display only 1 row of record.
Question:
How do i display the final result in only 1 ROW groupby CoursePaidForMonthYear.
I would like to get all data from Payment.*, TutorCourseCommissions.* and CoursePaidForMonthYear column in same row displaying (September, October, November)
Example:
referenceId| TutorId| CoursePaidForMonthYear |
1 | 1019 | September, October, November OR 9,10,11|
My work:
var result = from u in db.Users
join p in db.Payments on u.Id equals p.UserId
join tt in db.TutorCourseCommissions on p.Id equals tt.PaymentId into gtt
from tt in gtt.DefaultIfEmpty()
where u.Id == user.Id
GroupBy tt.CoursePaidForMonthYear ??
select new { u, p, tt };
foreach (var r in result)
{
Payment payment = new Payment();
payment.MonthToPay = (r.tt == null) ? null : common.GetMonthName(r.tt.CoursePaidForMonthYear.Month, true);
payment.Amount = r.p.Amount;
output.Add(payment);
}
return output;
What you need to do is group the months by the user and payment, and then perform an aggregation on the grouped months. In this case I used String.Join() to combine the distinct months coming from the commission.
This will give you results along the lines of { User = "John Doe", Payment = ..., Months = "January, February" }
var result = from u in db.Users
where u.UserID == user.Id
join p in db.Payments on u.Id equals p.UserId
join comm in db.TutorCourseCommissions
on p.Id equals comm.PaymentId
group common.GetMonthName(comm.CoursePaidForMonthYear,true)
by new { User = u, Payment = p } into g
select new
{
User = g.Key.User,
Payment = g.Key.Payment,
//...select out other properties here...
Months = String.Join(", ", g.Distinct())
};
Made a class with properties regarding all columns you required and then do the selection using its instance ...
Like
public TutorPayments
{
public int UserID{
get;
set;
}
public int PayType{
get;
set;
}
public int TutorID{
get;
set;
}
//and so on all columns property that you required
}
now you can get all these in your query by creating its instance in this way
var result = from u in db.Users
join p in db.Payments on u.Id equals p.UserId
join tt in db.TutorCourseCommissions on p.Id equals tt.PaymentId into gtt
from tt in gtt.DefaultIfEmpty()
where u.Id == user.Id
GroupBy tt.CoursePaidForMonthYear ??
select new TutorPayments {UserID = u.id,PayType = p.id,TutorID = tt.TutorId, ............ };

Categories