LINQ sum of one column and insert to another table C# - c#

i have two tables suck as the one below i wanna know how to sum "calorie" column based on name from table 1 and then insert the value to table 2
table1(PK->ID(int),Name(nvarchar),amount(int),calorie(int))
table2(pk->ID(int),name(nvarchar),totalcalorie(int))
+-------+--------+----------+--------------+
| int | name | amount | calorie |
+-------+--------+----------+--------------+
| 1 | a | 10 | 20 |
| 2 | b | 5 | 20 |
| 2 | b | 10 | 10 |
| 1 | a | 10 | 10 |
| 2 | b | 15 | 35 |
| 3 | c | 20 | 15 |
+-------+--------+----------+--------------+
something like this is my first table now imagine same kinda table for table2
only this time something like :
1-------a--------30
2-------b--------65
3-------c--------15
is this possible at all? what i wrote till now and doesn't work is this :
DataClasses1DataContext db = new DataClasses1DataContext();
var q = from row in db.table1
group row by new { row.name }
into grp
select new
{
grp.Key.name,
sum = grp.Sum(row => row.calorie)
};
db.SubmitChanges();

Now you are just selecting data. You need the block for insertion like the following:
var q = (from row in db.table1
group row by new { row.id, row.name } into grp
select new
{
grp.Key.id,
grp.Key.name,
sum = grp.Sum(s => s.calorie)
}).ToList();
foreach(var item in q)
{
var e = new db.table2Entity
{
id = item.id,
name = item.name,
totalcalorie = item.sum
};
db.Table2.AddObject(e);
}
db.SaveChanges();

I think that you do not see the result on you databse after db.SubmitChanges() wright ? Linq query should work fine but Submit doesn't see the change becouse there is no change in table2. You only select data and group it from table1. Please debug and see what is in q variable.

Related

How to concatenate multiple rows into a single row in ASP.NET MVC EF

I have 3 tables:
Recipe
RecipeIngredient (fk RecipeId)
RecipeTag (fk RecipeId)
Recipe
+-----+------------+-------------+------+
| Id | Name | Ingredients | Tags |
+-----+------------+-------------+------+
| 99 | Mango Sago | | |
| 100 | Tuna Melt | | |
+-----+------------+-------------+------+
RecipeIngredient
+-----+----------+------------+---------------------------------------------+----------+
| Id | Quantity | UOM | Name | RecipeId |
+-----+----------+------------+---------------------------------------------+----------+
| 115 | 2 | Pieces | Whole Ripe Mangoes | 99 |
| 116 | 1 | Pieces | Jolly Coconut Milk, 400ml | 99 |
| 117 | 2 | Tablespoon | Sugar | 99 |
| 118 | 1 | Cup | Cooked Tapioca Pearls | 99 |
| 119 | NULL | NULL | Mango Cubes | 99 |
| 120 | 1 | Pieces | Doña Elena 100% Tuna Shredded 185g, drained | 100 |
| 121 | 2 | Tablespoon | White Onion, chopped | 100 |
| 122 | 2 | Tablespoon | Jolly Real Mayonnaise | 100 |
| 123 | 1 | Tablespoon | Celery or Pickle Relish, finely chopped | 100 |
| 124 | 8 | Pieces | White Bread | 100 |
| 125 | 4 | Pieces | Cheddar or Mozzarella Cheese | 100 |
+-----+----------+------------+---------------------------------------------+----------+
RecipeTag
+----+-----------------+----------+
| Id | Name | RecipeId |
+----+-----------------+----------+
| 72 | Filipino Desert | 99 |
| 73 | Quick Recipe | 99 |
| 74 | Quick Recipe | 100 |
+----+-----------------+----------+
How do I add all the RecipeIngredient to the Ingredients column in the Recipe table and add all the RecipeTag to the Tags column in the Recipe table in the controller?
public JsonResult GetAllRecipes()
{
var recipes = db.Recipes.OrderBy(a => a.Name).ToList();
return new JsonResult { Data = recipes, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
public JsonResult GetAllRecipes()
{
var recipes = (from rec db.Recipes
join ing in db.Ingredients on rec.Id equals ing.RecipeId into subIngrs
from subIngr in subIngrs.DefaultIfEmpty()
join tag in db.RecipeTags on rec.Id equals tag.RecipeId into subTags
from subTag in subTags.DefaultIfEmpty()
order by rec.Name
select new
{
rec.Id,
rec.Name,
Quantity = subIngr == null ? null : subIngr.Quantity,
IngrName = subIngr == null ? null : subIngr.Name,
UOM = subIngr == null ? null : subIngr.UOM,
TagName = subTag == null ? null : subTag.Name
}).ToList()
.GroupBy(x => new { x.Id, x.Name }).Select(x => new
{
x.Key.Id,
x.Key.Name,
Ingredients = string.Join("," x.Where(y => y.IngrName != null).Select(y => $"{y.Quantity} {y.UOM} {y.Name}").Distinct()),
Tags = string.Join("," x.Where(y => y.TagName != null).Select(y => y.TagName).Distinct())
}).ToList();
return new JsonResult { Data = recipes, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
You can use STUFF if you want to do it in sql.
SELECT a.Id,
Recipe = a.Name,
Ingredient = STUFF((
SELECT ','
+ CAST(b.Quantity AS NVARCHAR(10)) + ' '
+ b.UOM + ' '
+ b.Name
FROM dbo.RecipeIngredient b
WHERE a.Id = b.RecipeId
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, ''),
Tag = STUFF((
SELECT ',' + c.Name
FROM dbo.RecipeTag c
WHERE a.ID = c.RecipeId
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
FROM Recipe a
Here's a Demo.
To execute the stored procedure and return the results as a json in your controller method
var recipies = db.Database.SqlQuery<RecipeVM>("NameOfStoredProcedure");
return Json(recipes, JsonRequestBehavior = JsonRequestBehavior.AllowGet);
where RecipeVM is
public class RecipeVM
{
public int Id { get; set; }
public string Name { get; set; }
public string Ingredient { get; set; }
public string Tag { get; set; }
}
Assuming you have set up your navigation properties correctly (i.e. Recipe contains public virtual ICollection<RecipieIngredient> Ingredients { get; set; } etc) then to get the data in the concatenated format you want,
public JsonResult GetAllRecipes()
{
var recipes = db.Recipes
.OrderBy(r => r.Name)
.ToList() // this is necessary because we need Linq to Objects for the string formatting
.Select(r => new // can be anonymous objects because we are returning a JsonResult
{
Id = r.Id,
Name = r.Name,
Ingredients = r.Ingredients
.Select(i => string.Format("{0} {1} {2}", i.Quantity, i.UOM, i.Name).TrimStart())
.Aggregate((c, n) => c + ", " + n),
Tags = r.Tags
.Select(t => t.Name)
.Aggregate((c, n) => c + ", " + n)
});
return Json(recipes, JsonRequestBehavior = JsonRequestBehavior.AllowGet);
}
Side note, your RecipeIngredient table indicates nullable values for Quantity and UOM hence the TrimStart. I am assuming that if either Quantity or UOM is null, then the other is also null
Alternatively, (in LINQ to SQL) you can use
var recipes = (from r in db.Recipies
join i in db.RecipeIngredient on r.Id equals i.RecipeId into Ingedients
join t in db.RecipeTag on r.Id equals t.RecipeId into Tags
orderby r.Name
select new
{
Name = r.Name,
Ingedients = Ingedients,
Tags = Tags
}).ToList()
.Select(x => new
{
Name = x.Name,
Ingredients = x.Ingedients
.Select(y => string.Format("{0} {1} {2}", y.Quantity, y.UOM, y.Name).Trim())
.Aggregate((c, n) => c + ", " + n),
Tags = x.Tags
.Select(y => y.Name)
.Aggregate((c, n) => c + ", " + n)
});
return Json(recipes, JsonRequestBehavior = JsonRequestBehavior.AllowGet);
I'm not exactly sure what you're trying to accomplish, but if you're trying to programatically insert this data from user input, you could just iterate over the ingredients/tags and build a string to insert into the relevant tables.
If you're trying to do this from existing data, then I'm not sure EF is the tool to use. I would just write SQL scripts to handle that.

Linq .GroupBy() with count

I have a table that I need to summarize in a report. This is my sample table.
Orders
_____________________________________
CustomerId | CustomerName | OrderType
___________|______________|__________
1 | Adam | Shoe
1 | Adam | Shoe
1 | Adam | Shoe
1 | Adam | Hat
1 | Adam | Hat
2 | Bill | Shoe
2 | Bill | Hat
3 | Carl | Sock
3 | Carl | Hat
I am trying to summarize this to pass back in my viewmodel without a loop. This is the result that I am attempting to achieve.
CustomerName | Shoe | Hat | Sock | Total Orders
------------ | ---- | --- | ---- | ------------
Adam | 3 | 2 | 0 | 5
Bill | 1 | 1 | 0 | 2
Carl | 0 | 1 | 1 | 2
//var resultList = dbContext.Orders.OrderBy(o => o.CustomerId);
How can I use GroupBy and Count to achieve my desired results? Would that be the best approach to take?
group clause (C# Reference)
var summary = from order in dbContext.Orders
group order by order.CustomerId into g
select new {
CustomerName = g.First().CustomerName ,
Shoe = g.Count(s => s.OrderType == "Shoe"),
Hat = g.Count(s => s.OrderType == "Hat"),
Sock = g.Count(s => s.OrderType == "Sock"),
TotalOrders = g.Count()
};
if items are fixed:
public List<OrderViewModel> GetCustOrders()
{
var query = orders
.GroupBy(c => c.CustomerName)
.Select(o => new OrderViewModel{
CustomerName = o.Key,
Shoe = o.Where(c => c.OrderType == "Shoe").Count(c => c.CustomerId),
Hat = o.Where(c => c.OrderType == "Hat").Count(c => c.CustomerId),
Sock = o.Where(c => c.OrderType == "Sock").Count(c => c.CustomerId),
Total = o.Count(c => c.CustomerId)
});
return query;
}
use SQL is one option, i tested it and get exactly what you want:
select p.*, t.total as 'Total Orders' from
(
select CustomerName, count(CustomerId) total from Orders group by CustomerName
) as t inner join
(
select * from Orders
pivot(count(CustomerId)
for OrderType in ([Shoe], [Hat], [Sock])
) as piv
)as p on p.CustomerName = t.CustomerName

Join a multiple tables get clone only demand not supply

Plantdemand
Id | FId | FY
------------------
22 | 1 | 2011-15
No.PlantDemand
Id | PDId | CId | Demand
------------------------
1 | 22 | 1 | 100
2 | 22 | 2 | 200
3 | 22 | 3 | 300
^
"- Id of plantDemand
PlantSupply
Id | FId | DId | FY
---------------------
11 | 1 | 22 | 2012-13
^
"-Id of plantDemand
No.PlantSuply
ID | PSId | CId | Supply
---------------------------
1 | 11 | 1 | 10
2 | 11 | 2 | 10
^
"--Id of PlantSupply
I am stuck to get a CId entries not in table No.PlantSupply of FId=1 like to get a clone who demand enter but not supplied
var getNoofPlantDemand = (from r in getdemand
join nd in context.tbl_NoOfPlantDemanded on r.PlantDemandId equals nd.PlantDemandId into list1
from l1 in list1.DefaultIfEmpty()
join p in context.PlantationTypes on r.PlantationTypeId equals p.Id into list3
from l3 in list3.DefaultIfEmpty()
select new
{}).toList()
var getCloneDemand = (from r in getNoofPlantDemand
join cl in context.Clones on r.CloneId equals cl.Id into list4
from l4 in list4.DefaultIfEmpty()
var getPlantSupply = (from r in getCloneDemand
join s in context.PlantSupply on r.PlantDemandId equals s.DemandId into list
from l1 in list.DefaultIfEmpty()
join ns in context.No.PlantSupply on l1.Id equals ns.PSId into list1
from l2 in list1.DefaultIfEmpty()
where r.CloneId != l2.CloneId && r.PlantDemandId==l1.DemandId && r.PlantationTypeId == l2.PlantationTypeId
select new
{}).toList()
my requirement:
Id | FId | FY | CId | Demand
22 | 1 | 2011-012 | 3 | 300
Please let me know if anybody know how can i get the clone those are not supplied only a demand entry

Group and count in linq C#

I have a query that needs to retrieve 3 fields:
| MaintenanceID | MaintenanceIDCount | StatusID |
| 1 | 2 | -1 |
| 3 | 2 | -1 |
The field MaintenanceIDCount (like the name says), is the count of MaintenanceID column.
My basic query expression is above:
var result = from m in Maintenance
select new
{
m.MaintenanceID,
m.StatusID
}
The result of this query is:
| MaintenanceID | StatusID |
| 1 | -1 |
| 1 | -1 |
| 3 | -1 |
| 3 | -1 |
How can I group and mount my query to retrieve a column with the MaintenanceID column count?
Some tips?
from m in Maintenance
group m by new { m.MaintenanceID, m.StatusID } into g
select new {
g.Key.MaintenanceID,
g.Key.StatusID,
MaintenanceIDCount = g.Count()
}

Join with count and multiple conditions - LINQ C#

I have a property database and I am trying to get all properties added by an user. The main table is called 'Property' and there are other tables which are 'PropertyPhotos', 'City' etc. A sample database is as follows:
'Property' table
PropertyId| Area| State| UserId | ...
1 | 1 | 1 | AAA | ...
2 | 2 | 3 | BBB | ...
3 | 1 | 1 | AAA | ...
'PropertyPhotos'
PropertyPhotoId| PropertyId| FileName | MainPic
1 | 1 | x1.jpg | 1
2 | 1 | X2.jpg | 0
3 | 2 | x3.jpg | 1
4 | 3 | x4.jpg | 1
5 | 3 | x5.jpg | 0
6 | 3 | x6.jpg | 0
'AreaLookUp'
AreaLookUpId | AreaDescription
1 | London
2 | Birmingham
3 | Manchester
I am trying to write a LINQ query to get information on property added by a particular user. But I am stuck when trying to retrieve the 'FileName' of the MainPic and also get count. See code below with comments.
So, for the data above, this query should return the following for "UserId = AAA"
PropertyId | ... | MainPicSrc | PhotoCount
1 | ... | x1.jpg | 2
3 | ... | xr4jpg | 3
Please help!
public IEnumerable<PropertyExcerptViewModel> GetAddedPropertyVmByUserId(string userId)
{
var addedProperties = from p in db.Property where p.UserId == userId
join pp in db.PropertyPhotos on p.PropertyId equals pp.PropertyId
join a in db.AreaLookUp on p.Area equals a.AreaLookUpId
select new PropertyExcerptViewModel
{
PropertyId = p.PropertyId,
PropertyType = p.PropertyType,
TransactionType = p.TransactionType,
IsPropertyDisabled = p.IsPropertyDisabled,
IsPropertyVerified = p.IsPropertyVerified,
IsPropertyNotified = p.IsPropertyNotified,
MainPicSrc = pp.FileName, // How to put where condition to only get FileName of just the Main Pic
PhotoCount = pp.Count(), // How to get count of all pics with a particular proprtyId
Price = p.Price,
NoOfBedrooms = p.NoOfBedrooms,
Area = a.AreaLookUpDescription,
ShortDescription = (p.Description.Length > 300) ? p.Description.Substring(0,300) : p.Description
};
return addedProperties.ToList();
}
I think where statement might be easier if you care about clear match
var data=(from c in db.Property from v in db.PropertyPhotos from
n in db.AreaLookUpId
where c.PropertyId==v.PropertyId && c.Area==n.AreaLookUpId && c.UserId=="AAA"
// the rest is your select
PhotoCount = v.Where(j=>j. PropertyId==c.PropertyId).Count()
This also works - I ended up doing it this way
var addedProperties = from p in db.Property
join ppic in db.PropertyPhotos on p.PropertyId equals ppic.PropertyId into pp
join a in db.AreaLookUp on p.Area equals a.AreaLookUpId
join cal in db.CalendarEvent on p.PropertyId equals cal.PropertyId into c
where p.UserId == userId
select new PropertyExcerptViewModel
{
PropertyId = p.PropertyId,
PropertyType = p.PropertyType,
PropertyCategoryDescription = pc.PropertyCategoryDescription,
TransactionType = p.TransactionType,
IsPropertyDisabled = p.IsPropertyDisabled,
IsPropertyVerified = p.IsPropertyVerified,
IsPropertyNotified = p.IsPropertyNotified,
MainPicSrc = pp.Where(e => e.MainPic == true).FirstOrDefault().PhotoLocation,
PhotosCount = pp.Count(),
Price = p.Price,
NoOfBedrooms = p.NoOfBedrooms,
Area = a.AreaLookUpDescription,
ShortDescription = (p.Description.Length > 300) ? p.Description.Substring(0, 300) : p.Description,
LatestCalendarEvent = c.OrderByDescending(e => e.DateSaved).FirstOrDefault()
};
return addedProperties.ToList();

Categories