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);
Related
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();
i have the following problem, i need access to items of sales line from salesheader, when i try access by entity works fine by lazy loading, but i try map with Automapper 6
canĀ“t access to Item from sales header
thanks
public class SalesHeader
{
public int DocumentNo { get; set; }
public virtual ICollection<PostedSalesLine> SalesLines { get; set; }
}
public class SalesLine
{
public int LineNo { get; set; }
public int DocumentNo { get; set; }
public int ItemId { get; set; }
public virtual Item Item { get; set; }
public int Quantity { get; set; }
public decimal Amount { get; set; }
}
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
public decimal UnitCost { get; set; }
public decimal UnitPrice { get; set; }
}
var result = unitOfWork.SalesHeader.GetById(documenNo);
Mapper.Initialize(cfg => cfg.CreateMap<SalesHeader, SalesHeaderDTO>()
return Mapper.Map<SalesHeaderDTO>(result);
Done!
Dont use lazy loading, it creates a mess of proxys
public IEnumerable<SalesHeader> GetAllFullDocuments()
{
return SalesContext.SalesHeader.Include(sh => sh.SalesLines.Select(i => i.Item))
.Include(sh => sh.SellToCustomer)
.Include(sh => sh.BillToCustomer)
.ToList();
}
I'm building a simple messaging system with the following data model:
public partial class Conversation
{
public Conversation()
{
this.Messages = new HashSet<Message>();
this.Customers = new HashSet<Customer>();
this.MessagingHubConnections = new HashSet<MessagingHubConnection>();
}
public int Id { get; set; }
public int BoatId { get; set; }
public System.DateTime TimeCreated { get; set; }
public virtual ICollection<Message> Messages { get; set; }
public virtual Boat Boat { get; set; }
public virtual ICollection<Customer> Customers { get; set; }
public virtual ICollection<MessagingHubConnection> MessagingHubConnections { get; set; }
}
public partial class Message
{
public int Id { get; set; }
public int ConversationId { get; set; }
public string Text { get; set; }
public bool IsRead { get; set; }
public System.DateTime TimeSend { get; set; }
public int CustomerId { get; set; }
public virtual Conversation Conversation { get; set; }
public virtual Customer Customer { get; set; }
}
When a customer opens his account dashboard, I want to display a list of all the conversations. This should be ordered according to the following rule: The first conversation in the list is the one with a message with the latest Message.TimeSent. If the conversation has no messages, it has to pick the Conversation.TimeCreated.
The code below is what I have right now but this is obviously not working when a Conversation has no messages. The variable conversations in the code below is an IQueryable<Conversation>.
var orderedConversations = conversations.OrderByDescending(c => c.Messages.Max(m => m.TimeSend));
Anyone who can help me out?
By projecting the TimeSend into DateTime? before Max()-ing it, you can obtain a (DateTime?)null when the collection is empty instead of getting an InvalidOperationException. And then, you can null-coalesce this result with TimeCreated:
var orderedConversations = conversations
.OrderByDescending(c =>
c.Messages
.Select<Message, DateTime?>(x => x.TimeSend)
.OrderByDescending(x => x)
.FirstOrDefault() ??
c.TimeCreated);
I am in need of some assistance with an Entity Framework query. I have the following entities:
public class Invoice
{
public Guid Id { get; set; }
public DateTime CreateDate { get; set; }
[ForeignKey("CreatedById")]
public virtual ApplicationUser CreatedBy { get; set; }
public Guid CreatedById { get; set; }
public bool Approved { get; set; }
public virtual ICollection<InvoiceDetail> Details { get; set; }
}
public class InvoiceDetail
{
public Guid Id { get; set; }
[ForeignKey("InvoiceId")]
public virtual Invoice Invoice { get; set; }
public Guid InvoiceId { get; set; }
public string Item { get; set; }
public string Description { get; set; }
public decimal Quantity { get; set; }
public decimal UnitCost { get; set; }
public decimal Discount { get; set; }
}
I am trying to sum the total of all the items where an invoice is Approved. The problem I'm having is the syntax on getting to the InvoiceDetail level once I filter for the Approved = 1:
var myInvoices = context.Invoices.Where(i => i.CreatedById == userId).Include(i => i.CreatedBy).Include(i => i.Details);
var approvedTotal = myInvoices.Where(i => i.Approved == 1).Select([GET TO DETAILS???]);
// my goal is to get the following sum for each detail for all of the approved invoices:
// ((d.Quantity * d.UnitCost) - d.Discount)
Assuming that you wanted to get a sum total of all details after the given calculation had been performed you could do something like this:
var approvedTotal = invoices.Where(invoice => invoice.Approved)
.Select(invoice => invoice.Details.Sum(detail => ((detail.Quantity * detail.UnitCost) - detail.Discount)));
So this gives you one total per invoice.
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
});