Save list to to database - c#

I have created a function on my restaurant review site that finds the cuisine of the last review and then finds other reviews of the same cuisines with a greater average score and then saves the restaurant id of those reviews into a table on the database. However I keep on getting the error:
Cannot assign method group to an implicitly-typed local variable.
on the line restaurantid = choices.Any help would be grateful.
var averagescore = db.Reviews
.Where(r => r.Cuisine == review.Cuisine)
.Average(r => r.score);
var choices = (from r in db.Reviews
where r.score <= averagescore
select r.RestaurantId).ToList;
foreach (var item in choices)
{
var suggestion = new Suggestion()
{
id = review.id,
Userid = review.UserId,
restaurantid = choices
};
db.Suggestions.Add(suggestion);
db.SaveChanges();
}

Following line:
var choices = (from ...).ToList;
Should be:
var choices = (from ...).ToList();
Secondly, it looks to me that restaurantid is of type int. With your code you're assigning a List<int> to the int. This should be item, from the loop.

You need to make the following change:
var averagescore = db.Reviews
.Where(r => r.Cuisine == review.Cuisine)
.Average(r => r.score);
var choices = (from r in db.Reviews
where r.score <= averagescore
select r.RestaurantId).ToList;
foreach (var item in choices)
{
var suggestion = new Suggestion()
{
id = review.id,
Userid = review.UserId,
restaurantid = item //here was your problem, you need to assign an id not a list of ids
};
db.Suggestions.Add(suggestion);
db.SaveChanges();
}

Have you tried like this:
var choices = (from r in db.Reviews
where r.score <= averagescore
select r).ToList;
foreach (var item in choices)
{
var suggestion = new Suggestion()
{
id = item.id,
Userid = item.UserId,
restaurantid = item.Restaurantid
};
db.Suggestions.Add(suggestion);
db.SaveChanges();
}

Related

Unable to get a distinct list that contains summed values

I have posted this earlier but the objective of what I am trying to achieve seems to have lost hence re-posting it to get explain myself better.
I have a collection that has duplicate productnames with different values. My aim is to get a list that would sum these productnames so that the list contains single record of these duplicates.
For e.g
If the list contains
Product A 100
Product A 200
The result object should contain
Product A 300
So as you can see in my code below, I am passing IEnumerable allocationsGrouped to the method. I am grouping by productname and summing the Emv fields and then looping it so that I created a new list of the type List and pass it to the caller method. The problem what I seeing here is on the following line of code Items = group. Items now contains original list without the sum. Hence the inner foreach loop runs more than ones because there are duplicates which defeats my purpose. I finally need to return result object that has non duplicate values which are summed based on the above criteria. Could you please tell me where I am going wrong.
private static List<FirmWideAllocationsViewModel> CreateHierarchy(string manStratName, IEnumerable<FIRMWIDE_MANAGER_ALLOCATION> allocationsGrouped, List<FirmWideAllocationsViewModel> result)
{
var a = allocationsGrouped
.Where(product => !string.IsNullOrEmpty(product.PRODUCT_NAME))
.GroupBy(product => product.PRODUCT_NAME)
.Select(group => new
{
ProductName = group.Key, // this is the value you grouped on - the ProductName
EmvSum = group.Sum(x => x.EMV),
Items = group
});
var b = a;
var item = new FirmWideAllocationsViewModel();
item.Hierarchy = new List<string>();
item.Hierarchy.Add(manStratName);
result.Add(item);
foreach (var ac in b)
{
var productName = ac.ProductName;
var emvSum = ac.EmvSum;
foreach (var elem in ac.Items)
{
var item2 = new FirmWideAllocationsViewModel();
item2.Hierarchy = new List<string>();
item2.Hierarchy.Add(manStratName);
item2.Hierarchy.Add(elem.PRODUCT_NAME);
item2.FirmID = elem.FIRM_ID;
item2.FirmName = elem.FIRM_NAME;
item2.ManagerStrategyID = elem.MANAGER_STRATEGY_ID;
item2.ManagerStrategyName = elem.MANAGER_STRATEGY_NAME;
item2.ManagerAccountClassID = elem.MANAGER_ACCOUNTING_CLASS_ID;
item2.ManagerAccountingClassName = elem.MANAGER_ACCOUNTING_CLASS_NAME;
item2.ManagerFundID = elem.MANAGER_FUND_ID;
item2.ManagerFundName = elem.MANAGER_FUND_NAME;
item2.Nav = elem.NAV;
item2.EvalDate = elem.EVAL_DATE.HasValue ? elem.EVAL_DATE.Value.ToString("MMM dd, yyyy") : string.Empty;
item2.ProductID = elem.PRODUCT_ID;
item2.ProductName = elem.PRODUCT_NAME;
item2.UsdEmv = Math.Round((decimal)elem.UsdEmv);
item2.GroupPercent = elem.GroupPercent;
item2.WeightWithEq = elem.WEIGHT_WITH_EQ;
result.Add(item2);
}
}
return result;
}
change it to:
var result = allocationsGrouped
.Where(product => !string.IsNullOrEmpty(product.PRODUCT_NAME))
.GroupBy(product => product.PRODUCT_NAME)
.Select(group => {
var product = group.First();
return new FirmWideAllocationsViewModel()
{
Hierarchy = new List<string>() { manStratName, product.PRODUCT_NAME },
FirmID = product.FIRM_ID,
FirmName = product.Item.FIRM_NAME,
ManagerStrategyID = product.MANAGER_STRATEGY_ID,
ManagerStrategyName = product.MANAGER_STRATEGY_NAME,
ManagerAccountClassID = product.MANAGER_ACCOUNTING_CLASS_ID,
ManagerAccountingClassName = product.MANAGER_ACCOUNTING_CLASS_NAME,
ManagerFundID = product.MANAGER_FUND_ID,
ManagerFundName = product.MANAGER_FUND_NAME,
Nav = product.NAV,
EvalDate = product.EVAL_DATE.HasValue ? product.EVAL_DATE.Value.ToString("MMM dd, yyyy") : string.Empty,
ProductID = product.PRODUCT_ID,
ProductName = product.PRODUCT_NAME,
UsdEmv = Math.Round((decimal)product.UsdEmv),
GroupPercent = product.GroupPercent,
WeightWithEq = product.WEIGHT_WITH_EQ,
//assign aggregate Sum here
EmvSum = group.Sum(x => x.EMV),
};
});

LINQ Group By Join

I'm struggling with what is a rather simple SQL select statement. How can this be translated into LINQ?
select
o.IdOrder, Date, s.suma, name, adresa
from
Clients c
join
Orders o on (c.IdClient = o.IdClient)
join
(select IdOrder, sum(price) suma
from OrderProduct
group by IdOrder) s on (o.IdOrder = s.IdOrder);
If you could point me in the right direction, I would greatly appreciate it.
This is what I have so far:
var y = from w in db.OrderProducts
group w by w.IdOrder into TotaledOrder
select new
{
IdOrder = TotaledOrder.Key,
price = TotaledOrder.Sum(s => s.price)
};
var i = 0;
var cc = new dynamic[100];
foreach (var item in y)
{
cc[i++] = db.Orders.Where(t => t.IdOrder == item.IdOrder)
.Select(p => new
{
IdOrder = item.IdOrder,
price = item.price,
}).Single();
}
Your SQL doesn't really give an idea on your underlying structure. By a guess on column names:
var result = from o in db.Orders
select new {
IDOrder = o.IDOrder,
Date = o.Date,
Suma = o.OrderProduct.Sum( op => op.Price),
Name = o.Client.Name,
Adresa = o.Client.Adresa
};
(I have no idea what you meant by the loop in your code.)

Returning List value using linq C#

Actually I want to return the data from different lists based on Date. When i'm using this i'm getting data upto #Var result but i'm unnable to return the data. The issue with this is i'm getting error #return result. I want to return the data #return result. I'm using Linq C#. Can anyone help me out?
public List<CustomerWiseMonthlySalesReportDetails> GetAllCustomerWiseMonthlySalesReportCustomer()
{
var cbsalesreeport = (from cb in db.cashbilldescriptions
join c in db.cashbills on cb.CashbillId equals c.CashbillId
join p in db.products on cb.ProductId equals p.ProductId
select new
{
Productamount = cb.Productamount,
ProductName = p.ProductDescription,
CashbillDate = c.Date
}).AsEnumerable().Select(x => new ASZ.AmoghGases.Model.CustomerWiseMonthlySalesReportDetails
{
Productdescription = x.ProductName,
Alldates = x.CashbillDate,
TotalAmount = x.Productamount
}).ToList();
var invsalesreeport = (from inv in db.invoices
join invd in db.invoicedeliverychallans on inv.InvoiceId equals invd.InvoiceId
select new
{
Productamount = invd.Total,
ProductName = invd.Productdescription,
InvoiceDate = inv.Date
}).AsEnumerable().Select(x => new ASZ.AmoghGases.Model.CustomerWiseMonthlySalesReportDetails
{
Productdescription = x.ProductName,
Alldates = x.InvoiceDate,
TotalAmount = x.Productamount
}).ToList();
var abc = cbsalesreeport.Union(invsalesreeport).ToList();
var result = (from i in abc
group i by new { Date = i.Alldates.ToString("MMM"), Product = i.Productdescription } into grp
select new { Month = grp.Key, Total = grp.Sum(i => i.TotalAmount) });
**return result;**
}
You can either convert your result to a List before returning it using return result.ToList() or make your method return an IEnumerable<CustomerWiseMonthlySalesReportDetails> instead of List.
As your result is an enumeration of anonymous types you have to convert them to your CustomerWiseMonthlySalesReportDetails-type first:
select new CustomerWiseMonthlySalesReportDetails{ Month = grp.Key, Total = grp.Sum(i => i.TotalAmount) });
Assuming your type has exactly the members returned by the select.
EDIT: So your code should look like this:
var result = (from i in abc
group i by new { Date = i.Alldates.ToString("MMM"), Product = i.Productdescription } into grp
select new CustomerWiseMonthlySalesReportDetails{ Month = grp.Key, Total = grp.Sum(i => i.TotalAmount) });
return result.ToList();
You can assume Alldates property if is date of one of groups that month of date is in right place:
var result = (from i in abc
group i by new { Date = i.Alldates.ToString("MMM"), Product = i.Productdescription }
into grp
select new CustomerWiseMonthlySalesReportDetails{
Productdescription = grp.Key.Product,
TotalAmount = grp.Sum(i => i.TotalAmount),
Alldates =grp.First(i=>i.Alldates ) })
.ToList();

query to get all action during for each hour

i want to run and print a query that shows the number of orders per each hour in a day(24).
should look like:
hour-1:00, number of orders-5
hour-2:00, number of orders-45
hour-3:00, number of orders-25
hour-4:00, number of orders-3
hour-5:00, number of orders-43
and so on...
i try:
public void ShowBestHours()
{
using (NorthwindDataContext db = new NorthwindDataContext())
{
var query =
from z in db.Orders
select new Stime
{
HourTime = db.Orders.GroupBy(x => x.OrderDate.Value.Hour).Count(),
};
foreach (var item in query)
{
Console.WriteLine("Hour : {0},Order(s) Number : {1}", item.HourTime, item.Count);
}
}
}
public class Stime
{
public int HourTime { get; set; }
public int Count { get; set; }
}
You need to change your query to
var query =
from z in db.Orders
group z by z.OrderDate.Value.Hour into g
select new Stime{ HourTime = g.Key, Count=g.Count () };
or alternatively
var query = db,Orders.GroupBy (o => o.OrderDate.Value.Hour).Select (
g => new Stime{ HourTime=g.Key, Count=g.Count () });
In my copy of Northwind all of the OrderDate values are dates only so the result is just
HourTime = 0, Count = 830.
I'm assuming you're just experimenting with grouping. Try grouping by day of week like this
var query = db.Orders.GroupBy (o => o.OrderDate.Value.DayOfWeek).Select (
g => new { DayOfWeek=g.Key, Count=g.Count () });
which gives a more useful result.
You aren't setting Stime.Count anywhere in your query and you aren't grouping by hour correctly. I haven't seen your exact setup of course, but I think the following should work for you.
var query =
from z in db.Orders
group z by z.OrderDate.Value.Hour into g
select new Stime() { HourTime = g.Key, Count = g.Count() };
foreach (var item in query)
{
Console.WriteLine("Hour : {0},Order(s) Number : {1}", item.HourTime, item.Count);
}
Try this:
public void ShowBestHours()
{
using (NorthwindDataContext db = new NorthwindDataContext())
{
var query = db.Orders.GroupBy(x => x.OrderDate.Value.Hour).OrderByDescending(x => x.Count()).Select(x => new Stime { HourTime = x.Key, Count = x.Count() });
foreach (var item in query)
{
Console.WriteLine("Hour : {0},Order(s) Number : {1}", item.HourTime, item.Count);
}
}
}

Nested Group by LINQ

I am unable to solve this problem with the LINQ Query.
So we have the table structure as follows:
Id || bug_category || bug_name || bug_details || bug_priority
I want to group by bug_category first. For each bug_category, I want to in turn group by bug__priority.
So basically I want something like :
bug_category = AUDIO :: No of BUGS --> Critical = 3, Medium = 2 and Low = 7 bugs.
bug_category = VIDEO :: No of BUGS --> Critical = 5, Medium = 1 and Low = 9 bugs.
The below query returns all unique combinations of category AND customer_priority:
(where RawDataList is simply a List of data which has the above mentioned structure )
var ProceesedData = from d in RawDataList
group d by new { d.bug_category, d.bug_priority } into g
select new
{
g.Key.bug_category,
g.Key.bug_priority
};
The below query returns the category followed by a list of records in that category:
var ProceesedData = from d in RawDataList
group d by d.bug_category into g
select new { g.Key, records = g
};
But I am unable to proceed further as ProcessedData(the return variable) is an unknown type. Any thoughts on this?
This is an easier way to accomplish nested groupings. I've tested it for in memory collections, whether or not your particular DB provider will handle it well might vary, or whether it performs well is unknown.
Assuming you had two properties, and wanted to group by both State and Country:
var grouped = People
.GroupBy(l => new { l.State, l.Country})//group by two things
.GroupBy(l=> l.Key.Country)//this will become the outer grouping
foreach(var country in grouped)
{
foreach(var state in country)
{
foreach(var personInState in state)
{
string description = $"Name: {personInState.Name}, State: {state.StateCode}, Country: {country.CountryCode}";
...
}
}
}
I suspect you want (names changed to be more idiomatic):
var query = from bug in RawListData
group bug by new { bug.Category, bug.Priority } into grouped
select new {
Category = grouped.Key.Category,
Priority = grouped.Key.Priority,
Count = grouped.Count()
};
Then:
foreach (var result in query)
{
Console.WriteLine("{0} - {1} - {2}",
result.Category, result.Priority, result.Count);
}
Alternatively (but see later):
var query = from bug in RawListData
group bug by new bug.Category into grouped
select new {
Category = grouped.Category,
Counts = from bug in grouped
group bug by grouped.Priority into g2
select new { Priority = g2.Key, Count = g2.Count() }
};
foreach (var result in query)
{
Console.WriteLine("{0}: ", result.Category);
foreach (var subresult in result.Counts)
{
Console.WriteLine(" {0}: {1}", subresult.Priority, subresult.Count);
}
}
EDIT: As noted in comments, this will result in multiple SQL queries. To obtain a similar result structure but more efficiently you could use:
var dbQuery = from bug in RawListData
group bug by new { bug.Category, bug.Priority } into grouped
select new {
Category = grouped.Key.Category,
Priority = grouped.Key.Priority,
Count = grouped.Count()
};
var query = dbQuery.ToLookup(result => result.Category,
result => new { result.Priority, result.Count };
foreach (var result in query)
{
Console.WriteLine("{0}: ", result.Key);
foreach (var subresult in result)
{
Console.WriteLine(" {0}: {1}", subresult.Priority, subresult.Count);
}
}
I think you're searching something like that:
var processedData =
rawData.GroupBy(bugs => bugs.bug_category,
(category, elements) =>
new
{
Category = category,
Bugs = elements.GroupBy(bugs => bugs.bug_priority,
(priority, realbugs) =>
new
{
Priority = priority,
Count = realbugs.Count()
})
});
foreach (var data in processedData)
{
Console.WriteLine(data.Category);
foreach (var element in data.Bugs)
Console.WriteLine(" " + element.Priority + " = " + element.Count);
}
You can do it like this
var retList = (from dbc in db.Companies
where dbc.IsVerified && dbc.SellsPCBs && !dbc.IsDeleted && !dbc.IsSpam && dbc.IsApproved
select new
{
name = dbc.CompanyName,
compID = dbc.CompanyID,
state = dbc.State,
city = dbc.City,
businessType = dbc.BusinessType
}).GroupBy(k => k.state).ToList();
List<dynamic> finalList = new List<dynamic>();
foreach (var item in retList)
{
finalList.Add(item.GroupBy(i => i.city));
}

Categories