Display the sum of the orders of the month in chart - asp.net

I don`t know how to display, at the beginning the sum of the orders of the month in the table in the asp.net MVC.
My data in table Order look like:
DateCreated | TotalPrice
2017-02-06 | 400
2017-02-06 | 300
2017-03-06 | 100
2017-03-06 | 50
And I want to get mountly sum of TotalPrice, like this:
DateCreated | TotalPrice
2017-02 | 700
2017-03 | 150
My model class Order:
public int orderId { get; set; }
public string UserId { get; set; }
public virtual ApplicationUser User { get; set; }
[StringLength(100)]
public string firstName { get; set; }
[StringLength(150)]
public string lastName { get; set; }
[StringLength(150)]
public string address { get; set; }
[StringLength(20)]
public string phoneNumber { get; set; }
public string email { get; set; }
public string comment { get; set; }
public DateTime dateCreated { get; set; }
public OrderState orderState { get; set; }
public decimal totalPrice { get; set; }
public List<OrderIteam> OrderIteams { get; set; }
I try to write something like this to display the sum of the orders of the month in the table :
public ActionResult ListOrder()
{
var result =
from s in db.Orders
group s by new { date = new DateTime(s.dateCreated.Year, s.dateCreated.Month, 1) } into g
select new
{
dateCreated = g.Key.date,
sumTotalPrice = g.Sum(x => x.totalPrice)
};
return View(result);
}
My view looks like this
I am getting the error message:
The model item passed into the dictionary is of type 'System.Data.Entity.Infrastructure.DbQuery1[<>f__AnonymousType52[System.DateTime,System.Decimal]]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[Sklep_Internetowy.Models.Order]'.
At the end I would like to show that the sum of the orders of a given month as the chart below:
Chart

Currently the LINQ query below returns DbQuery instance with anonymous type instead of IEnumerable collection:
var result = from s in db.Orders
group s by new { date = new DateTime(s.dateCreated.Year, s.dateCreated.Month, 1) } into g
select new
{
dateCreated = g.Key.date,
sumTotalPrice = g.Sum(x => x.totalPrice)
}; // returns System.Data.Entity.Infrastructure.DbQuery<AnonymousTypeN>
The reason behind thrown InvalidOperationException here is simply because a different type of data has been passed into the view which requires IEnumerable<Sklep_Internetowy.Models.Order>.
Try change return type to Order instead using anonymous type one:
var result = from s in db.Orders
group s by new { date = new DateTime(s.dateCreated.Year, s.dateCreated.Month, 1) } into g
select new Order // return Sklep_Internetowy.Models.Order here
{
dateCreated = g.Key.date,
sumTotalPrice = g.Sum(x => x.totalPrice)
};
At this point, the return type of LINQ query above becomes IQueryable<Sklep_Internetowy.Models.Order> which implements IEnumerable, hence it doesn't require conversion (but you may still need to use collection aggregate methods to execute it, e.g. ToList()).
Related issues:
The model item passed into the dictionary is of type 'System.Data.Entity.Infrastructure.DbQuery', but this dictionary requires a model item of type B
The model item passed into the dictionary is 'System.Data.Entity.Infrastructure.DbQuery`, but requires 'System.Collections.Generic.IEnumerable

Related

Retrieve data form two or more tables by lambda expression

I have two tables, Entity and Payment.
Entity table:
EntityID EntityName Country Currency
----------------------------------------
1 xyz cou1 cur1
2 abc cou2 cur2
3 efg cou1 cur1
Payment table:
PaymentID Amount EntityID
-----------------------------
1 1000 1
2 3000 2
3 1000 1
I want to get sum of amount of Entity with respect to currency like
currency Amount
-----------------
cur1 2000
cur2 3000
My code
var data = db.Payment.GroupBy(x => x.Entity.Currency);
With this code I can get data which is group by currency, but I can't sum it.
Thanks in advance
So you have defined two classes in your data context:
class Entitiy
{
public int EntityID { get; set; }
public string EntityName { get; set; }
public string Country { get; set; }
public string Currency { get; set; }
}
class Payment
{
public int PaymentID { get; set; }
public double Amount { get; set; }
public int EntityID { get; set; }
public Entitiy Entity { get; set; }
}
And later in code you have created a database context, which can be simulated by this:
var db = new { Payment = new Payment[0] };
Then you use it with your code above:
var data = db.Payment.GroupBy(x => x.Entity.Currency);
And to answer your question how you sum each currency, I suggest this:
var sums = data.Select(grp => new {
Currency = grp.Key,
Sum = grp.Sum(p => p.Amount)
});
Now you have an enumeration of currencies and their respective sums.
Try this solution:
var sum = from p in db.Payment
from e in db.Entity.Where(e=>e.EntityID == p.EntityID).DefaultIfEmpty()
group e by e.Currency into Entities
select new
{
currency = Entities.Key,
Amount = Entities.Sum(s=>s.Amount)
};

LINQ Group By Type for each user

I have a list of objects with following structure
public class Jobs
{
public string EmployeeName { get; set; }
public string JobNumber { get; set; }
public string JobPriority { get; set; }
public string JobType { get; set; }
public string Description { get; set; }
public string Status { get; set; }
public string CreatedByUser { get; set; }
public DateTime DueDate { get; set; }
public DateTime UpdateDate { get; set; }
}
What I would like to do is to return a List of objects which contains
EmployeeName,
Total Count of Jobs assigned to him,
Job Type & Count of each job type assigned to an emploee.
So in essence, I would need list of records to appear like the attached image below. I will use the result from the LINQ query and bind it to a asp.net GridView
Andrew
Total Jobs: 12
Build Jobs: 3
Config Jobs: 4
Delivery Jobs: 3
How can I achieve a result using the linq from the initial list that i have. I guess for pros, this would be a very simple and straight-forwad LINQ query.
EDIT: Added for final structure that i want:
I would like to get the result from LINQ into following structure. i.e. List of UserJob
public class UserJob
{
public string EmployeeName { get; set; }
public int TotalJobs { get; set; }
public List<UserJobGroup> Tickets { get; set; }
}
public class UserJobGroup
{
public string JobType { get; set; }
public int JobCount { get; set; }
}
dasblinkenlight already explained it. With your specific classes, it's even easier - all you need is to follow the steps he described and translate them to LINQ. You should really be able to do that yourself, especially with query syntax:
var result =
(from job in jobList
group job by job.EmployeeName into employeeNameJobs
let jobTypeJobs =
(from job in employeeNameJobs
group job by job.JobType into jobTypeJobs
select new UserJobGroup
{
JobType = jobTypeJobs.Key,
JobCount = jobTypeJobs.Count()
})
.ToList()
select new UserJob
{
EmployeeName = employeeNameJobs.Key,
TotalJobs = jobTypeJobs.Sum(item => item.JobCount),
Tickets = jobTypeJobs
})
.ToList();
Let's walk through the structure of the query that you are trying to build:
At the top level you need groups by employee
At the employee level you need two related, but separate, things:
You need separate counts by job, and
You also need the total of these counts
Now let's build the query. Start with GroupBy for the top level:
var empGroups = jobList.GroupBy(j => j.EmployeeName);
Convert each group to a dictionary with EmployeeName serving as the key, and job group counts stored as values:
var jobCountsByEmployee = empGroups
.ToDictionary(
g => g.Key
, g => g.GroupBy(j => j.JobType)
.ToDictionary(jg => jg.Key, jg => jg.Count())
);
Finally, add totals to construct the result that you want:
var res = jobCountsByEmployee
.ToDictionary(
p => p.Key
, p => new {
Total = p.Value.Sum(jc => jc.Value)
, CountByJob = p.Value
}
);

EF 5.0 Foreign Key Not Updating

I know there are some other questions regarding this-- but I was unable to get them to solve my problem.
I have the following classes:
public class Category
{
public Category()
{
Products = new List<Product>();
}
public int Id { get; set; }
public string Name { get; set; }
public List<Product> Products { get; set; }
public override string ToString()
{
return String.Format("{0}{1}", Id, Name);
}
}
and
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public Category Category { get; set; }
public override string ToString()
{
return String.Format("{0}{1}", Id, Name);
}
}
I've got some code which attempts to update both a product and it's category:
using (var ctx = GetCtx())
{
var beverages = new Category {Id = 1 };
var milk = new Product { Name = "MILK", Id = 4, Category = new Category { Id = 1} };
ctx.Entry(milk).State = System.Data.EntityState.Modified;
ctx.SaveChanges();
}
this results in the following sql statement:
update [dbo].[Products]
set [Name] = #0, [Price] = #1
where ([Id] = #2)
#0: MILK
#1: 0
#2: 4
I can't figure out how to make sure that the Category for the particular product is updated. I thought about adding a property to Product for Category_Id but this results in an additional column being generated in my database.
EDIT:
I think I figured this out-- after watching Julia Lerman's series on EF (Pluralsight)-- the way to set up this class is like this:
public class Product
{
public int Id { get; set; }
[Required]
[MaxLength(200)]
public string Name { get; set; }
public virtual Category Category { get; set; }
public int CategoryId { get; set; }
}
This results in only one foreign key column in the Products table. The Category of the Product gets updated when updating the CategoryId property.
You have to do two jobs, so do them in two operations...
var cat = ctx.Categories.FirstOrDefault(c=>c.Id == 1);
if(cat == null){
cat = new Category{Id=1};
ctx.Categies.Add(cat);
}
cat.Products.Add(new Product{Name="Milk", Id=4};
try{
ctx.SaveChanges();
}catch(Exception ex){
return RedirectToResponse("someone else got in first with that category Id");
}

asp.net mvc querying from different table to view

I need to query data from 2 table
public class UserProfile
{
public int UserId { get; set; }
public string UserName { get; set; }
public string Name { get; set; }
}
and
public class PrivateMessage
{
public int MessageId { get; set; }
public string Sender { get; set; }
public string Receiver { get; set; }
public string Subject { get; set; }
public string Message { get; set; }
private DateTime _date = DateTime.Now;
public DateTime sentDate { get { return _date; } set { _date = value; } }
}
and this what i tried on my controller
public ActionResult Index()
{
var x = User.Identity.Name;
var query = from p in db.PrivateMessages
join u in db.UserProfiles on p.Sender equals u.UserName
where p.Receiver == x
select new
{
u.UserName,
u.Name,
p.Receiver,
p.Subject,
p.Message,
p.sentDate
};
return View(query);
}
this is my view model
#model IEnumerable<SeedSimple.Models.PrivateMessage>
but i got this error
The model item passed into the dictionary is of type
'System.Data.Entity.Infrastructure.DbQuery1[<>f__AnonymousType95[System.String,System.String,System.String,System.String,System.DateTime]]',
but this dictionary requires a model item of type
'System.Collections.Generic.IEnumerable`1[SeedSimple.Models.PrivateMessage]'.
all i want is to get username and name from UserProfile table and receiver, subject, message and sentDate on PrivateMessage table
Well you're passing as a Model an anonymous type yet you have a strongly typed View.
You can either create a new ViewModel that contains all the fields you're using for your query and pass that, or you can pass all the properties in the ViewBag (not a pretty solution).
EDIT
Thought I'd give you an example.
Here is a ViewModel containing the data you need:
public class MessageViewModel
{
public string UserName { get; set; }
public string Name { get; set; }
public string Receiver { get; set; }
public string Subject { get; set; }
public string Message { get; set; }
public DateTime SentDate { get; set; }
}
In your view:
#model IEnumerable<SeedSimple.Models.MessageViewModel>
In your Controller:
public ActionResult Index()
{
var x = User.Identity.Name;
var result = from p in db.PrivateMessages
join u in db.UserProfiles on p.Sender equals u.UserName
where p.Receiver == x
select new MessageViewModel
{
UserName = u.UserName,
Name = u.Name,
Receiver = p.Receiver,
Subject = p.Subject,
Message = p.Message,
SentDate = p.sentDate
};
return View(result);
}
I hope this helps.

RavenDB Query on Datetime with value in collection offset

I am trying to query RavenDB on a Datetime which is being offset by a entry in a collection. As shown below, I have an AppointmentReminder object which contains many AppointmentReminderJobs. I'd like to query for AppointmentReminders where the AppointmentReminderJob is due to run.
My models are as follows:
public class AppointmentReminder
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public DateTime AppointmentDateTime { get; set; }
public ReminderStatus ReminderStatus { get; set; }
public List<AppointmentReminderJob> AppointmentReminderJobs { get; set; }
}
public class AppointmentReminderJob
{
public JobStatus JobStatus { get; set; }
public int DaysPrior { get; set; }
}
My controller and attempt to retrieve a list of AppointmentReminders which have current jobs to run (I know this Where clause isn't complete, but I've tried to simplify it with no luck):
public ActionResult GetJobsQueuedListCurrent()
{
var jobsqueuedlist = RavenSession.Query<AppointmentReminder>()
.Where(appointmentreminder => appointmentreminder.AppointmentReminderJobs.Any(x => appointmentreminder.AppointmentDateTime < DateTime.Now.AddDays(x.DaysPrior)))
.OrderBy(appointmentreminder => appointmentreminder.AppointmentDateTime)
.Take(20)
.ToList();
return View("List", jobsqueuedlist);
}
Calling the above yields a response of:
variable 'x' of type 'ProjectName.Models.AppointmentReminderJob' referenced from scope '', but it is not defined
I am trying to set up an index like so:
public class JobsQueuedListCurrent : AbstractIndexCreationTask<AppointmentReminder, JobsQueuedListCurrent.IndexResult>
{
public class IndexResult
{
public int Id { get; set; }
public DateTime JobDateTime { get; set; }
}
public JobsQueuedListCurrent()
{
Map = appointmentreminders => from appointmentreminder in appointmentreminders
from job in appointmentreminder.AppointmentReminderJobs
select new
{
Id = appointmentreminder.Id,
JobDateTime = appointmentreminder.AppointmentDateTime.AddDays(job.DaysPrior)
};
Store(x => x.Id, FieldStorage.Yes);
Store(x => x.JobDateTime, FieldStorage.Yes);
}
}
Now, I'm querying and getting expected results using:
var jobsqueuedlist = RavenSession.Query<JobsQueuedListCurrent.IndexResult, JobsQueuedListCurrent>()
.Where(x=>x.JobDateTime >= DateTime.Now)
.As<AppointmentReminder>()
.Take(20)
.ToList();
return View("List", jobsqueuedlist);
My last question regarding this would be, my map/index can definitely result in multiple entries of the same document id (appointmentreminder), but my resulting list contains only 1 instance of the document. I'm happy with the way that works, I'm just not sure if I should be performing a reduce or doing something else in my code or just let Raven handle it like it seems like it is doing?
You cannot create such a query. This would require RavenDB to perform computation during query, and that is not allowed.
RavenDB only allows queries on the data in the index.
What you can do it setup the computation in the index, and then query on that.

Resources