Get row count using group by in entityframework - c#

I have a TheaterMovieShowTime entity in that entity I want to get the row count by grouping on a particular column say TheaterMovieDetailID .
Here is my entity :
public class TheaterMovieShowTime
{
public int TheaterMovieShowTimeID { get; set; }
public int TheaterMovieDetailID { get; set; }
public int TheaterShowTimeID { get; set; }
public virtual TheaterMovieDetail TheaterMovieDetails { get; set; }
public virtual TheaterShowTime TheaterShowTime { get; set; }
}
Here is my TheaterMovieDetail entity:
public class TheaterMovieDetail
{
public int TheaterMovieDetailID { get; set; }
public int TheaterID { get; set; }
public int MovieID { get; set; }
public DateTime DateFrom { get; set; }
public DateTime DateTo { get; set; }
public virtual Movie Movie { get; set; }
public virtual Theater Theater { get; set; }
public virtual ICollection<TheaterMovieShowTime> TheaterMovieShowTimes { get; set; }
}
I try this :
var p = _theaterMovieShowTimeService.GetAllTheaterMovieShowTime()
.GroupBy(x => x.TheaterMovieDetailID)
.Select(x => new TheaterMovieShowTimeSummaryViewModel
{
TheaterName = x.FirstOrDefault().TheaterMovieDetails.Theater.TheaterName,
MovieName = x.FirstOrDefault().TheaterMovieDetails.Movie.MovieName,
NoOfShows=???????? // get the no of rows here
});
How do I get NoOfShows here that is no of rows grouped by TheaterMovieDetailID .
Would appreciate any help offered. Let me know if you need any other information to help answer this question

Use linq Count() function:
var p = _theaterMovieShowTimeService.GetAllTheaterMovieShowTime()
.GroupBy(x => x.TheaterMovieDetailID)
.Select(x => new TheaterMovieShowTimeSummaryViewModel
{
TheaterName = x.FirstOrDefault().TheaterMovieDetails.Theater.TheaterName,
MovieName = x.FirstOrDefault().TheaterMovieDetails.Movie.MovieName,
NoOfShows= x.Count() // get the no of rows here
});

Related

Linq Group by relative entites

My scenario: Users will be able to create lists and add items to these lists. What I want to do is to find the items in the lists created by the users at most.
Item Entity
public class Item:BaseEntity
{
public string Name { get; set; }
public decimal Price { get; set; }
public decimal DiscountedPrice{ get; set; }
public virtual ICollection<ItemList> ItemLists { get; set; }
}
Item List Entity
public class ItemList:BaseEntity
{
public string Name { get; set; }
public string Description { get; set; }
public int UserId { get; set; }
public ICollection<Item> Items { get; set; }
[ForeignKey("UserId")]
public virtual User User { get; set; }
}
User Entity
public class User:BaseEntity
{
public string Name { get; set; }
public string Surname { get; set; }
public string Gsm { get; set; }
public string Email { get; set; }
public virtual ICollection<ItemList> ItemLists{ get; set; }
}
my DTO
public class TopItemsForUsers
{
[BsonRepresentation(BsonType.ObjectId)]
[BsonId]
public string ItemId { get; set; }
public string UserId { get; set; }
public int Quantity { get; set; }
}
My Item repository
var query = _context.Items.Include(l => l.ItemLists)
.GroupBy(g => g.ItemLists)
.Select(z => new TopItemsInLists { ItemId = z.Key.ToString(), Quantity = z.Count() })
.OrderByDescending(z => z.Quantity)
.Take(10);
I want to get products that are very present in users' lists
Where am I doing wrong? If anyone has any other suggestions
Try this query. I hope I understand question correctly.
var query =
from u in _context.Users
from il in u.ItemLists
from i in il.Items
group i by new { UserId = u.Id, ItemId = i.Id } into g
select new TopItemsInLists
{
UserId = g.Key.UserId.ToString(),
ItemId = g.Key.ItemId.ToString(),
Quantity = g.Count()
};
query = query
.OrderByDescending(z => z.Quantity)
.Take(10);

Find sum of unique parameter in list - linq

I have list of lines, the lines contains list of calls (call has DestinationNumber property)
here's my line model
public class Line
{
public Line()
{
Calls = new List<Call>();
Messages = new List<Sms>();
Payments = new List<Payment>();
}
public int LineId { get; set; }
public int CustomerId { get; set; }
public Customer Customer { get; set; }
public Package Package { get; set; }
public ICollection<Call> Calls { get; set; }
public ICollection<Sms> Messages { get; set; }
public ICollection<Payment> Payments { get; set; }
public string LineNumber { get; set; }
public LineStatus Status { get; set; }
[DataType(DataType.DateTime)]
public DateTime? CreatedDate { get; set; }
[DataType(DataType.DateTime)]
public DateTime? RemovedDate { get; set; }
}
and here's my call model
public class Call
{
public int CallId { get; set; }
public int LineId { get; set; }
public Line Line { get; set; }
public DateTime DateOfCall { get; set; }
public int Duration { get; set; }
public string DestinationNumber { get; set; }
}
I want to Count() the number of unique calls
I tried something like that..
Lines.Sum(line=>line.Calls.Sum(call=>call.DestinationNumber.Where(/*if DestiantionNumber not counted before*/))
GroupBy approach this picks all calls by their DestinationNumber which exist only once x.Count() == 1 and counts them Count()
int result = line.Calls.GroupBy(x => x.DestinationNumber).Count(x => x.Count() == 1);
I think something like this should work:
var count = lines.SelectedMany(l => l.Calls)
.Select(c => c.DestinationNumber)
.Distinct()
.Count();

need to get id from IEnumerable<item>

So im trying to create a little website to help with my family's business.
I have two models, Jobs and Days.
public class Job
{
public int JobId { get; set; }
public int LotNum { get; set; }
public string Street { get; set; }
public string Suburb { get; set; }
public double PerHour { get; set; }
public string Description { get; set; }
}
public class Day
{
public int JobId { get; set; }
public int DayId { get; set; }
public DateTime Date { get; set; }
public double Hours { get; set; }
public string Details { get; set; }
public int Invoice { get; set; }
}
I need to make an Invoice, the invoice will be numbered. The days have the invoice number so ill be able to pick the days needed.
It would look something like this.
Date LotNum Street Suburb Hours
1/1/01 1 John Street Hurstville x hours
1/1/01 1 John Street Hurstville x hours
1/1/01 1 John Street Hurstville x hours
1/1/01 1 John Street Hurstville x hours
I am able to get the days with the specific invoice number using this:
vm.Days = _dayRepo.GetAll().Where(d => d.Invoice == id);
By doing so i have the date and hours of that day but now i need to get the job information. Both Day and Job have the JobId so i would be able to link them but i just dont know how.
This is what i have so far:
public IActionResult Invoice(int id)
{
CreateInvoiceViewModel vm = new CreateInvoiceViewModel();
vm.Days = _dayRepo.GetAll().Where(d => d.Invoice == id);
//vm.JobId =
vm.Jobs = _jobRepo.GetAll();
return View(vm);
}
My view looks like this:
#model CreateInvoiceViewModel
<table>
#foreach (var item in Model.)
{
<tr>
<td>#item.Date.Date.ToString("dd/MM/yy")</td>
<td>#item.Hours</td>
</tr>
}
</table>
I dont know what to put in for the foreach.
Thanks in advance!
you just need a join query. Define Your ViewModel like:
public class InvoiceViewModel
{
public DateTime Date { get; set; }
public int LotNum { get; set; }
public string Street { get; set; }
public string Suburb { get; set; }
public double Hours { get; set; }
}
Create a join query and convert it to ViewModel:
public IActionResult Invoice(int id)
{
var query = from d in _dayRepo.GetAll()
join job in _jobRepo.GetAll() on d.JobId equals job.JobId
select new { Date=d.Date, LotNum= job.job , Street =job.Street , Suburb =job.Suburb , Hours =d.Hours };
IEnumerable<InvoiceViewModel> viewModel = query.Select(c => new InvoiceViewModel()
{
Date=query.Date,
LotNum=query.LotNum,
Street=query.Street,
Suburb=query.Suburb,
Hours=query.Hours
});
return View(viewModel);
}
This should result in an IEnumerable with your ids
var ids = _dayRepo.GetAll().Where(d => d.Invoice == id).Select(x => x.JobId);
You can also add .ToList() to the end if you want it as a list.
This is more or less how I would set it up, or at least the beginnings of how.
(I'm using EntityFrameworkCore and yes I understand that you are using repos at the moment)
public class Job
{
public int Id { get; set; }
public int LotNum { get; set; }
public string Street { get; set; }
public string Suburb { get; set; }
public double PerHour { get; set; }
public string Description { get; set; }
// Navigation Helper
public virtual ICollection<InvoiceJobRelationship> Invoices { get; set; }
}
public class Day
{
public int Id { get; set; }
public DateTime Date { get; set; }
public double Hours { get; set; }
public string Details { get; set; }
// Navigation Helper
public virtual ICollection<InvoiceDayRelationship> Invoices { get; set; }
}
public class Invoice
{
public int Id { get; set; }
// Navigation Helpers
public virtual ICollection<InvoiceJobRelationship> Jobs { get; set; }
public virtual ICollection<InvoiceDayRelationship> Days { get; set; }
}
public class InvoiceDayRelationship
{
public int InvoiceId { get; set; }
// Navigation Helper
[ForeignKey("InvoiceId")]
public Invoice Invoice { get; set; }
public int DayId { get; set; }
// Navigation Helper
[ForeignKey("DayId")]
public Day Day { get; set; }
}
public class InvoiceJobRelationship
{
public int InvoiceId { get; set; }
// Navigation Helper
[ForeignKey("InvoiceId")]
public Invoice Invoice { get; set; }
public int JobId { get; set; }
// Navigation Helper
[ForeignKey("JobId")]
public Job Job { get; set; }
}
Then in your context
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<InvoiceDayRelationship>()
.HasKey(id => new { id.DayId, id.InvoiceId });
builder.Entity<InvoiceJobRelationship>()
.HasKey(ij => new { ij.JobId, ij.InvoiceId });
}
public DbSet<Invoice> Invoices { get; set; }
public DbSet<Day> Days { get; set; }
public DbSet<Job> Jobs { get; set; }
public DbSet<InvoiceDayRelationship> InvoiceDays { get; set; }
public DbSet<InvoiceJobRelationship> InvoiceJobs { get; set; }
Then you would be able to call pretty much anything you would like.
(Example Query)
(from x in context.Invoices where x.Id == id select x).Include(inv => inv.Days).Include(inv => inv.Jobs);

How to avoid to load collection property in Entity Framework

When I select artile, it select user, but user has a collection of article, so article select user again. May be recursive cause out of memory ,
The calling processing is :
article=>user=>article=>user...
ef entities is :
public partial class article
{
public int id { get; set; }
public string title { get; set; }
public string cont { get; set; }
public Nullable<int> uid { get; set; }
public System.DateTime addtime { get; set; }
public Nullable<int> colid { get; set; }
public virtual user user { get; set; }
public virtual column column { get; set; }
}
public partial class user
{
public user()
{
this.roleusers = new HashSet<roleuser>();
this.articles = new HashSet<article>();
}
public int id { get; set; }
public string email { get; set; }
public string uname { get; set; }
public string upass { get; set; }
public virtual ICollection<roleuser> roleusers { get; set; }
public virtual ICollection<article> articles { get; set; }
}
mysql EF operation class is :
public class ArtDao
{
readonly crmEntities _ent = new crmEntities();
public List<article> PageArts(int start, int limit, out int total)
{
var ll =
_ent.articles.OrderByDescending(o => o.id)
.Skip(start)
.Take(limit)
.ToList();
total = _ent.articles.Count();
return ll;
}
}
How to avoid to eager load the collection property roleusers and articles ?
You need to set LazyLoad on you edmx properties, and manually load only first level childs with Include() method when selecting:
public List<article> PageArts(int start, int limit, out int total)
{
var ll =
_ent.articles.OrderByDescending(o => o.id)
.Skip(start)
.Take(limit)
.Include(o => o.user)
.ToList();
total = _ent.articles.Count();
return ll;
}
You need to implement it in another class, wich can be a partial class.

How can I create a LINQ expression that joins four tables and allows a where on the topmost table?

I have the following classes:
public partial class Topic
{
public Topic()
{
this.SubTopics = new List<SubTopic>();
}
public int TopicId { get; set; }
public string Name { get; set; }
public int SubjectId { get; set; }
public virtual Subject Subject { get; set; }
public virtual ICollection<SubTopic> SubTopics { get; set; }
}
public partial class SubTopic
{
public SubTopic()
{
this.Problems = new List<Problem>();
}
public int SubTopicId { get; set; }
public int TopicId { get; set; }
public string Name { get; set; }
public virtual ICollection<Problem> Problems { get; set; }
public virtual Topic Topic { get; set; }
}
public class Problem
{
public Problem()
{
this.Questions = new List<Question>();
}
public int ProblemId { get; set; }
public int SubTopicId { get; set; }
public string Title { get; set; }
public virtual SubTopic SubTopic { get; set; }
public virtual ICollection<Question> Questions { get; set; }
}
public class Question
{
public int QuestionId { get; set; }
public int ProblemId { get; set; }
public string Text { get; set; }
public virtual Problem Problem { get; set; }
}
Can someone help tell me how I can construct a LINQ expression. What I need to do is to get just the QuestionId of the Questions that have a SubjectId = 0.
Here is a LINQ I created to get questions where the ProblemId was given:
var questions = _questionsRepository
.GetAll()
.Where(a => a.ProblemId == problemId)
.ToList();
For this could someone tell me how I can make the LINQ expression join all the above tables so I can enter a SubjectId = 0;
You have all the navigation properties needed, so you can just do :
var questions = _questionsRepository.GetAll()
.Where(m => m.Problem.SubTopic.Topic.SubjectId == 0)
.Select(m => m.QuestionId);
you may need some null check
.Where(m => m.Problem != null &&
m.Problem.SubTopic ! null &&
m.Problem.SubTopic.Topic != null &&
m.Problem.SubTopic.Topic.SubjectId == 0)
.Select(m => m.QuestionId);

Categories