GROUP BY LINQ ASP.NET MVC - asp.net-mvc

Let's suppose we have a Linq query like this:
int companyID = Convert.ToInt32(((UserIdentity)User.Identity).CompanyId);
var stock = from i in _stockService.GetStock()
join ur in _inventoryService.GetInventory() on i.ProductID equals ur.Id
where ur.ComapnyId == companyID
select new StockVM
{
Product = ur.ItemName,
Quantity = i.Quantity,
BatchID = i.BatchID,
StockStatus = i.StockStatus,
MfgDate = i.MfgDate,
ExpDate = i.ExpDate,
};
Result
How to do a "Group By Product" with sum of Quantity in this linq query?
I need to only get max ExpDate firstOrDefault

try something like this:
int companyID = Convert.ToInt32(((UserIdentity)User.Identity).CompanyId);
var stock = from i in _stockService.GetStock()
join ur in _inventoryService.GetInventory() on i.ProductID equals ur.Id
where ur.ComapnyId == companyID
group new { Quantity = i.Quantity } by new { ur.ItemName } into g
select new { Product = g.Key, TotalQuantity = g.Sum() } ).ToList() ;
List<StockVM> _lst = new List<StockVM>();
foreach(var item in stock ){
StockVM row = new StockVM();
row.Product = item.ItemName;
//....
_lst.Add(row);
}

Related

Linq Query to fetch data using non entity object

I'm trying to fetch the record from 3 tables by comparing the user Logged in name
Here is my code:
public ActionResult MeritList() //departmental merit listed students details with status 1
{
var username= HttpContext.Session["UserName"];
List<StdListModel> model = new List<StdListModel>();
var query = (from s in Context.tblStdDetails
join e in Context.tblStdEnrollments on s.ID equals e.StdReg_ref_id
//join d in Context.tblDepartments on e.Depart_ref_id equals d.ID
where s.Status == '1' && e.tblDepartment.DepartName == username
select new StdListModel
{
ID = s.ID,
Name = s.Name,
FatherName = s.FatherName,
CNIC = s.CNIC,
FormNo = s.FormNo,
DiaryNo = s.DiaryNo,
Status = s.Status
}).ToList();
foreach(var item in query)
{
model.Add(new StdListModel()
{
ID=item.ID,
Name=item.Name,
FatherName=item.FatherName,
CNIC=item.CNIC,
FormNo=item.FormNo,
DiaryNo=item.DiaryNo
});
}
return View(model);
}
Also Tried this Query
var query = (from s in Context.tblStdDetails
join e in Context.tblStdEnrollments on s.ID equals e.StdReg_ref_id
join d in Context.tblDepartments on e.Depart_ref_id equals d.ID
where s.Status == '1' && d.DepartName.Equals(username)
select new StdListModel
{
ID = s.ID,
Name = s.Name,
FatherName = s.FatherName,
CNIC = s.CNIC,
FormNo = s.FormNo,
DiaryNo = s.DiaryNo,
Status = s.Status
}).ToList();
But it does not return anything model=0, query =0, the database has right values and I don't get any error either.
please check username with tolower() and trim function.
e.tblDepartment.DepartName.ToLower().Trim() == username.ToLower().Trim()
or
e.tblDepartment.DepartName.ToLower().Trim().equals(username.ToLower().Trim())
I got the problem. It is in
s.Status == '1'
I just changed it into
s.Status == 1
and it works fetch the data from the database.

Apply Groupby in EF with suitable results

I am not much familiar with EF. I want to group rows based on IDs. I acheive this in SQL but I am getting some Issues with group by while implementeing in EF.
public ActionResult PropertyListing()
{
if (Session["UserID"] == null)
{
return RedirectToAction("Login", "Property");
}
return View();
}
public JsonResult GetSpurts()
{
PropertySpurts property;
List<PropertySpurts> listProperty = new List<PropertySpurts>();
var userID = Convert.ToInt32(Session["UserID"].ToString());
// IEnumerable<tblPropertyView> PropertyList;
var PropertyList = from p in dbEntity.tblPropertyViews
join c in dbEntity.tblProperties on p.PropertyID equals c.ID into j1
from j2 in j1.DefaultIfEmpty()
group j2 by p.PropertyID into grouped
select new { ParentId = grouped.Key, Count = grouped.Count(t => t.ID != null) };
if (PropertyList != null)
{
foreach (var item in PropertyList)
{
property = new PropertySpurts();
property.ID = (int)item.ParentId;
property.Title = item.tblProperty.Title;
listProperty.Add(property);
}
}
return Json(listProperty, JsonRequestBehavior.AllowGet);
}
PropertyID in tblPropertyView is Foreign Key to tblProperty ID. I want to get title of Property from tblProperty. Please help me to find Title and Count of PropertyViews
TIA
[SOLVED]
var PropertyList = from p in dbEntity.tblPropertyViews
join c in dbEntity.tblProperties on p.PropertyID equals c.ID into j1
from j2 in j1.DefaultIfEmpty()
group j2 by new
{
p.PropertyID,
p.tblProperty.Title
} into grouped
select new
{
ParentId = grouped.Key.PropertyID,
Title = grouped.Key.Title,
Count = grouped.Count(t => t.ID != null)
};
This solves my issue. But I want this should be orderby count.
var PropertyList = (from p in dbEntity.tblPropertyViews
join c in dbEntity.tblProperties on p.PropertyID equals c.ID into j1
from j2 in j1.DefaultIfEmpty()
group j2 by new
{
p.PropertyID,
p.tblProperty.Title
} into grouped
select new
{
ParentId = grouped.Key.PropertyID,
Title = grouped.Key.Title,
Count = grouped.Count(t => t.ID != null)
}).OrderByDescending(x => x.Count);

Linq query, how to orderby

I have a method that gets some data from the database by some linq queries. The data is shown as expected but not in the order I wan't. I need to sort the products I get from the database by the TotalQuantity property shown in query 1 and 2. Im trying to use OrdeBy but I'm not sure how to add it in this context. Need some help with this one.
This is my method:
public IList<BestsellersReportLine> DailyBestsellersReport()
{
OrderStatus os;
PaymentStatus ps;
ShippingStatus ss;
int billingCountryId = 0;
int recordsToReturn = 10;
int orderBy = 1;
int groupBy = 1;
var range = new
{
startTimeUtc = DateTime.Today.AddDays(-1),
endTimeUtc = DateTime.Today.AddSeconds(-1),
CreatedOnUtc = DateTime.Today.AddDays(-1),
};
var query1 = from opv in _opvRepository.Table
join o in _orderRepository.Table on opv.OrderId equals o.Id
join pv in _productVariantRepository.Table on opv.ProductVariantId equals pv.Id
join p in _productRepository.Table on pv.ProductId equals p.Id
where (o.CreatedOnUtc >= range.startTimeUtc && o.CreatedOnUtc <= range.endTimeUtc)
select opv;
var query2 = groupBy == 1 ?
//group by product variants
from opv in query1
group opv by opv.ProductVariantId into g
select new
{
EntityId = g.Key,
TotalAmount = g.Sum(x => x.PriceExclTax),
TotalQuantity = g.Sum(x => x.Quantity),
}
:
//group by products
from opv in query1
group opv by opv.ProductVariant.ProductId into g
select new
{
EntityId = g.Key,
TotalAmount = g.Sum(x => x.PriceExclTax),
TotalQuantity = g.Sum(x => x.Quantity),
};
switch (orderBy)
{
case 1:
{
query2 = query2.OrderByDescending(x => x.TotalQuantity);
}
break;
case 2:
{
query2 = query2.OrderByDescending(x => x.TotalAmount);
}
break;
default:
throw new ArgumentException("Wrong orderBy parameter", "orderBy");
}
if (recordsToReturn != 0 && recordsToReturn != int.MaxValue)
query2 = query2.Take(recordsToReturn);
var result = query2.ToList().Select(x =>
{
var reportLine = new BestsellersReportLine()
{
EntityId = x.EntityId,
TotalAmount = x.TotalAmount,
TotalQuantity = x.TotalQuantity
};
return reportLine;
}).ToList();
return result;
}
What about return
result.OrderBy(x => x.totalQuantity).ToList();
Update:
I can only think of adding .ToList() to the end again.
Remove the first ToList() after query2 as mentioned below:
var result = query2.Select(x =>
{
var reportLine = new BestsellersReportLine()
{
EntityId = x.EntityId,
TotalAmount = x.TotalAmount,
TotalQuantity = x.TotalQuantity
};
return reportLine;
}).ToList();

Error in linq join query in MVC 4

I am trying this query:
public ActionResult Index()
{
var topics = from t in db.Topics
join subs in db.Subjects on t.SubID equals subs.SubID
join mems in db.Members on t.MemberID equals mems.MemberID
select new ViewModel
{
TopicID = t.TopicID,
TDate = t.TDate,
Title = t.Title,
FileName = t.FileName,
Displays = t.Displays,
Description = t.Description,
SubName = subs.SubName,
FLName = mems.FLName
};
return View(topics);
}
But it causes the following Error:
The entity or complex type 'MySiteModel.ViewModel' cannot be constructed in a LINQ to Entities query.
I have an Entitity Class with above fields.
What is the problem? ????
Try convert it to List<> first.
var topics = (from t in db.Topics
join subs in db.Subjects on t.SubID equals subs.SubID
join mems in db.Members on t.MemberID equals mems.MemberID
select new ViewModel
{
TopicID = t.TopicID,
TDate = t.TDate,
Title = t.Title,
FileName = t.FileName,
Displays = t.Displays,
Description = t.Description,
SubName = subs.SubName,
FLName = mems.FLName
}).ToList();
Hope it helps

Adapting Linq Entity objects to Domain objects

I have the following code which adapts linq entities to my Domain objects:
return from g in DBContext.Gigs
select new DO.Gig
{
ID = g.ID,
Name = g.Name,
Description = g.Description,
StartDate = g.Date,
EndDate = g.EndDate,
IsDeleted = g.IsDeleted,
Created = g.Created,
TicketPrice = g.TicketPrice
};
This works very nicely.
However I now want to populate a domain object Venue object and add it to the gig in the same statement. Heres my attempt....
return from g in DBContext.Gigs
join venue in DBContext.Venues on g.VenueID equals venue.ID
select new DO.Gig
{
ID = g.ID,
Name = g.Name,
Description = g.Description,
StartDate = g.Date,
EndDate = g.EndDate,
IsDeleted = g.IsDeleted,
Created = g.Created,
TicketPrice = g.TicketPrice,
Venue = from v in DBContext.Venues
where v.ID == g.VenueID
select new DO.Venue
{
ID = v.ID,
Name = v.Name,
Address = v.Address,
Telephone = v.Telephone,
URL = v.Website
}
};
However this doesnt compile!!!
Is it possible to adapt children objects using the "select new" approach?
What am I doing so very very wrong?
Your inner LINQ query returns several objects, not just one. You want to wrap it with a call like:
Venue = (from v in DBContext.Venues
where v.ID == g.VenueID
select new DO.Venue
{
ID = v.ID,
Name = v.Name,
Address = v.Address,
Telephone = v.Telephone,
URL = v.Website
}).SingleOrDefault()
Your choice of Single() vs. SingleOrDefault() vs. First() vs. FirstOrDefault() depends on what kind of query it is, but I'm guessing you want one of the first two. (The "OrDefault" variants return null if the query has no data; the others throw.)
I also agree with Mike that a join might be more in line with what you wanted, if there's a singular relationship involved.
Why are you doing a join and a sub select? You can just use the results of your join in the creation of a new Venue. Be aware that if there is not a one to one relationship between gigs and venues you could run into trouble.
Try this:
return from g in DBContext.Gigs
join venue in DBContext.Venues on g.VenueID equals venue.ID
select new DO.Gig { ID = g.ID, Name = g.Name, Description = g.Description,
StartDate = g.Date, EndDate = g.EndDate, IsDeleted = g.IsDeleted,
Created = g.Created, TicketPrice = g.TicketPrice,
Venue = new DO.Venue { ID = venue.ID, Name = venue.Name,
Address = venue.Address, Telephone = v.Telephone,
URL = v.Website }

Resources