Subtracting quantity using Entity Model - c#

I am trying to subtract the field "QtyOnHand" in the table "Inventory" from the quantity in List. But I get this error:
Unable to cast object of type 'System.Collections.Generic.List`1[System.Int32]' to type 'System.IConvertible'.
It shows that the error occurs at:
var cartQty = (from i in items where i.ProductId == Convert.ToInt32(productId) select i.Qty).SingleOrDefault();
My code is the following:
protected void btnCheckout_Click(object sender, EventArgs e)
{
int inventoryQty;
List<Item> items = Session["Cart"] as List<Item>;
using (ProjectEntities myEntities = new ProjectEntities())
{
var productId = (from i in items select i.ProductId).ToList();
var cartQty = (from i in items where i.ProductId == Convert.ToInt32(productId) select i.Qty).SingleOrDefault();
var inventory = (from q in myEntities.Inventories
where q.ProductId == Convert.ToInt32(productId)
select q).SingleOrDefault();
inventoryQty = inventory.QtyOnHand - cartQty;
myEntities.SaveChanges();
Response.Redirect("~/Home.aspx");
}
}
Thanks in advance!

var productId = (from i in items select i.ProductId).ToList();
productId variable contains a list of items and you are trying to pass that to Convert.ToInt32 to method which is not expecting a collection of items!. That is causing the issue.
Since you are cart may have more than one item, you probably need to loop throug the productIds and do your other calculation.
var productIdList = (from i in items select i.ProductId).ToList();
foreach(var productId in productIdList)
{
var cartQty = (from i in items where i.ProductId == Convert.ToInt32(productId)
select i.Qty).SingleOrDefault();
// Your remaining code
}
I am assuming the productId in your cart item is of numeric value, but of string type. Then only the Convert.ToInt32 will work as it is expecting the string representation of some valid numeric value (Ex :"234")
If it is of int type, you do not need the Convert.ToInt32(productId) part in your where clause, just use i.ProductId==productId

Related

How do I drill down to specific data in my LINQ query result?

I want to drill down into a particular item in my data and output the list of results to the output window. My query result looks like this
private IEnumerable<DataRow> _data;
var query = from data in this._data
group data by data.Field<string>("Form Name") into groups //same as Form ID
select new
{
formName = groups.Key,
items = from d in groups
group d by d.Field<string>("Item Name") into grps
let name = grps.Key
let documentIDGroups = grps.GroupBy(t => t.Field<string>("Document ID"))
let documentIDGroupsCount = documentIDGroups.Count()
let distinctDocumentValueCount = from data in documentIDGroups
select new
{
docID = data.Key,
distinctDocValueCount = data.Where(t => string.IsNullOrEmpty(t.Field<string>("Document Value").Trim()) == false).Select(t => t.Field<string>("Document Value")).Distinct().Count()
}
let sum = distinctDocumentValueCount.Sum(t => t.distinctDocValueCount)
let distinctItemsNames = from data in grps
select data.Field<string>("Item Name").Distinct().Count()
let count = distinctItemsNames.Count()
select new
{
itemName = name,
documentIDGroups,
documentIDGroupsCount,
averageChoices = Math.Round(((decimal)sum / documentIDGroupsCount), 2),
distinctDocumentValueCount,
sum
}
};
So on that query result I want to drill down into a particular form name, and from there get a particular Item Name and so on
so the first step is to get the grouping of items and I have
var items = from d in query where d.formName == "someName" select d.items;
but I don't know how to isolate the items by a particular string.
I want to do the following
var item = from d in items where d.itemName == "anItemName" select d;
But I don't know the syntax.
Use the .FirstOrDefault extension if you expect a single item to be returned from your query. SO:
var item = (from d in items where d.itemName == "anItemName" select d).FirstOrDefault();

LINQ get find all with id in list

I am trying to figure out non query way to do return a list of all objects if their ID is in test list. Example below:
Hero - table
Columns: id = INT , name = STRING, age = INT, power = INT;
var testList = {1,2,3};
var secondArray = {};
foreach (var id in testList )
{
// check if ID in database
var item = db.Hero.ToList().Find(o => o.Id = id);
if( item != null)
{
secondArray.push(item);
}
}
Now i have seen this whole thing done in single line but cannot remember how it was done.
The result i am after is List of all objects containing that have ids 1,2,3.
You have to use Contains on testList:
var secondArray= db.Hero.Where (h=> testList.Contains(h.Id))
How about
var result = db.Hero.Where(x => testList.Contains(x.Id));
This would hit DB just once instead of 3 times.

sum of item prices that have the same item id

I want sum of all item prices in all rows in the database table that have the same item id. I mean the result should be one number and put it on textbox automatically when I choose a specific item id from dropdownlist
How can I do it in linq?
public double oIlstGetVouchersDetailjh(int nvoucherID)
{
Training_sNairoukhEntities1 sNairoukhEntities1 = new Training_sNairoukhEntities1();
double sum = (from Entity in sNairoukhEntities1.INV_InventoryItems
where Entity.ItemID == nvoucherID
select Entity.ItemPrice).sum();
return sum;
}
or
public double oIlstGetVouchersDetailjh(int nvoucherID)
{
Training_sNairoukhEntities1 sNairoukhEntities1 = new Training_sNairoukhEntities1();
double olstInvoicesSrech = from Entity in sNairoukhEntities1.INV_InventoryItems
group Entity by Entity.ItemID == nvoucherID into g
select g.sum(Entity => Entity.ItemPrice);
return olstInvoicesSrech;
}
but the second query give me this msg Cannot implicitly convert type 'System.Linq.IQueryable' to 'double
In your case, this will work:
Training_sNairoukhEntities1 sNairoukhEntities1 = new Training_sNairoukhEntities1();
double sum = (from Entity in sNairoukhEntities1.INV_InventoryItems
where Entity.ItemID == nvoucherID
select Entity.ItemPrice).Sum(); // Change sum to Sum
return sum;
Here's a simpler way:
sNairoukhEntities1.INV_InventoryItems.Where(item => item.ItemID == nvoucherID).Sum(item => item.ItemPrice);

Get list of child records

I have a database that looks like this:
tbl_Seminar
ID
isActive
tbl_SeminarFees
ID
seminar_id -- foreign key
fee_text
I want to get all seminars that are active (isActive ==1) and a list of the fees associated with that seminar. Each Seminar may have n records in tbl_SeminarFees that are its fees. I am able to return a linq structure that returns me a list of objects that look like this {seminar, SeminarFee} but I wanted to create a nested structure that looks like this:
{seminar, List<SeminarFee>}
What should my linq query look like?
here is my linq currently:
var results = from s in context.Seminar
join p in context.SeminarFees on
s.ID equals p.SeminarID
where s.IsActive == 1
select new
{
Seminar = s,
Fees = p
};
How do I change this to get a list of these: {seminar, List<SeminarFee>}
Thanks
UPDATE
#lazyberezovsky gave me a good idea to use a group join and into another variable. But then how do I loop through the result set. Here is what I have now:
foreach (var seminarAndItsFeesObject in results)
{
//do something with the seminar object
//do something with the list of fees
}
This however gives me the following error:
Argument type 'SeminarFees' does not match the
corresponding member type
'System.Collections.Generic.IEnumerable`1[SeminarFees]'
What am I doing wrong?
Thanks
You can use group join which groups inner sequence items based on keys equality (a.k.a. join..into) to get all fees related to seminar:
var results = from s in context.Seminar
join f in context.SeminarFees on
s.ID equals f.SeminarID into fees // here
where s.IsActive == 1
select new
{
Seminar = s,
Fees = fees
};
You can't call ToList() on server side. But you can map results on client later.
BTW You can define navigation property Fees on Seminar object:
public virtual ICollection<SeminarFee> Fees { get; set; }
In this case you will be able load seminars with fees:
var results = context.Seminar.Include(s => s.Fees) // eager loading
.Where(s => s.IsActive == 1);
var results = from s in context.Seminar
join p in context.SeminarFees on s.ID equals p.SeminarID
where s.IsActive == 1
group p by s into grouped
select new {
Seminar = grouped.Key,
Fees = grouped.ToList()
};

How to use LINQ-to-Entity to query by contained objects

Let's say I have a list of Boxes and in a box you can have multiple items.
Box (id)
Items (id, boxId)
I'm trying to build a linq to entity query that can return all the boxes that contains ALL specified items.
List<Box> FindBoxContainingAllSpecifiedItems(List<int> itemIds)
{
var q = from box in ctx.Boxes
where ???
}
Thanks for the help
It depends on the implementation of boxes. But lets for the moment say it has a property Items with the type IEnumerable<int>. In that case you could use the Intersect extension method to see if the items are all accounted for
var q = from box in ctx.Boxes
where box.Items.Intersect(itemIds).Count() == itemIds.Count;
Here is what I have found thanks to JaredPar contribution.
List<Location> FindLocationContainingAllItems(List<int> itemIds)
{
var itemQuery = from item in ctx.Items
select item;
// Workaround the Where In Clause (http://social.msdn.microsoft.com/Forums/en/adodotnetentityframework/thread/095745fe-dcf0-4142-b684-b7e4a1ab59f0)
itemQuery = itemQuery.Where(BuildContainExpression<Items, int>(i=> i.Id, itemIds));
int itemCount = itemIds.Count();
var locQuery = from loc in ctx.Locations
from box in loc.Boxes
where (from items in box.Items select items).Intersect(itemQuery).Count == itemCount
select loc;
return locQuery.ToList();
}

Categories