I have two lists
var stores = new[]
{
new { Code = 1, Name = "Store 1" },
new { Code = 2, Name = "Store 2" }
};
var orders = new[]
{
new { Code = 1, StoreCode = 1, TotalValue = 14.12 },
new { Code = 2, StoreCode = 1, TotalValue = 24.12 }
};
OUTPUT
StoreName = Store 1 | TotalValue = 38.24
StoreName = Store 2 | TotalValue = 0
How can I translate this into LINQ to SQL?
var lj = (from s in stores
join o in orders on s.Code equals o.StoreCode into joined
from j in joined.DefaultIfEmpty()
group s by new
{
StoreCode = s.Code,
StoreName = s.Name
}
into grp
select new
{
StoreName = grp.Key.StoreName,
TotalValue = ???
}).ToList();
When you doing group join, all orders related to store will be in group, and you will have access to store object. So, simply use s.Name to get name of store, and g.Sum() to calculate total of orders:
var lj = (from s in db.stores
join o in db.orders on s.Code equals o.StoreCode into g
select new {
StoreCode = s.Name,
TotalValue = g.Sum(x => x.TotalValue)
}).ToList();
Note - from your sample it looks like you don't need to group by store name and code, because code looks like primary key and it's unlikely you will have several stores with same primary key but different names.
Related
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.)
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();
I am trying to reproduce the following SQL query in Linq and need some help please.
select
dbo.Documents.DocId,
dbo.Documents.ReykerAccountRef,
dbo.Documents.ReykerClientId DocClientID,
CAAs.ClientId CAAClientIDCheck,
ClientData.FullName ClientFullName,
CAAs.IFAId,
AdvisorData.FullName AdvisorFullName
from dbo.Documents
left join
dbo.CAAs on dbo.Documents.ReykerAccountRef = dbo.CAAs.AccountRef
left join
dbo.hmsProfileDatas AS ClientData
on
dbo.CAAs.ClientId = ClientData.ReykerClientID
left join
dbo.hmsProfileDatas AS AdvisorData
on
dbo.CAAs.IFAId = AdvisorData.ReykerClientID
I am trying to link to the same table twice, once for a client fullname and the other for an Advisor fullname.
The basic sql I want to produce in linq is
select table1.*,table2.*,a.Fullname, b.Fullname
from table1
left join
table2 on table1.t2Id = table2.Id
left join
table3 AS a
on
table2.t3Id1 = table3.id1
left join
table3 AS b
on
table2.t3Id2 = table3.id2
So table one is joined to table2 and table2 has 2 foreign keys (t3Id1 and t3Id2) to table3 to different fields (id1 and id2).
This is what I have tried following some guidance, but it's not returning anything! What's going wrong?
var results3 = from doc in DataContext.Documents
from caa
in DataContext.CAAs
.Where(c => c.AccountRef == doc.ReykerAccountRef)
.DefaultIfEmpty()
from cpd
in DataContext.hmsProfileDatas
.Where(pdc => pdc.ReykerClientID == caa.ClientId)
.DefaultIfEmpty()
from apd
in DataContext.hmsProfileDatas
.Where(pda => pda.ReykerClientID == caa.IFAId)
.DefaultIfEmpty()
select new DocumentInList()
{
DocId = doc.DocId,
DocTitle = doc.DocTitle,
ReykerDocumentRef = doc.ReykerDocumentRef,
ReykerAccountRef = doc.ReykerAccountRef,
ClientFullName = cpd.FullName,
AdvisorFullName = apd.FullName,
DocTypeId = doc.DocTypeId,
DocTypes = doc.DocTypes,
DocDate = doc.DocDate,
BlobDocName = doc.BlobDocName,
UploadDate = doc.UploadDate,
};
I hope I understood your example correctly. Here's another simple example, that should give what you need:
private class User
{
public int UserId;
public string Name;
public int GroupId;
public int CollectionId;
}
public class Group
{
public int GroupId;
public string Name;
}
public class Collection
{
public int CollectionId;
public string Name;
}
static void Main()
{
var groups = new[] {
new Group { GroupId = 1, Name = "Members" },
new Group { GroupId = 2, Name = "Administrators" }
};
var collections = new[] {
new Collection { CollectionId = 1, Name = "Teenagers" },
new Collection { CollectionId = 2, Name = "Seniors" }
};
var users = new[] {
new User { UserId = 1, Name = "Ivan", GroupId = 1, CollectionId = 1 },
new User { UserId = 2, Name = "Peter", GroupId = 1, CollectionId = 2 },
new User { UserId = 3, Name = "Stan", GroupId = 2, CollectionId = 1 },
new User { UserId = 4, Name = "Dan", GroupId = 2, CollectionId = 2 },
new User { UserId = 5, Name = "Vlad", GroupId = 5, CollectionId = 2 },
new User { UserId = 6, Name = "Greg", GroupId = 2, CollectionId = 4 },
new User { UserId = 6, Name = "Arni", GroupId = 3, CollectionId = 3 },
};
var results = from u in users
join g in groups on u.GroupId equals g.GroupId into ug
from g in ug.DefaultIfEmpty()
join c in collections on u.CollectionId equals c.CollectionId into uc
from c in uc.DefaultIfEmpty()
select new {
UserName = u.Name,
GroupName = g != null ? g.Name : "<No group>",
CollectionName = c != null ? c.Name : "<No collection>"
};
}
It produces two join over one table to get data from other two tables.
Here's the output:
Ivan Members Teenagers
Peter Members Seniors
Stan Administrators Teenagers
Dan Administrators Seniors
Vlad <No group> Seniors
Greg Administrators <No collection>
Arni <No group> <No collection>
I want to group dvdlist by categoryid, Similar to this, but no DVDDataContext
This one works,
DvdDataContext db = new DvdDataContext();
var q = from b in db.DvdLists
group b by b.CategoryId into g
select new { CategoryID = g.Key, DvdLists = g };
I need the following kind of code, but the error occurs at GetTable()=g
DataContext db = new DataContext(conString);
var dvd = db.GetTable<DvdList>();
var query = from b in dvd
group b by b.CategoryId into g
select new { CategoryId = g.Key, GetTable<DvdList>()= g };
You cannot specify GetTable() in anonymous types. Try { CategoryId = g.Key, GetTable= g };
Hope it helps!
I am facing a scenario where I have to filter a single object based on many objects.
For sake of example, I have a Grocery object which comprises of both Fruit and Vegetable properties. Then I have the individual Fruit and Vegetable objects.
My objective is this:
var groceryList = from grocery in Grocery.ToList()
from fruit in Fruit.ToList()
from veggie in Vegetable.ToList()
where (grocery.fruitId = fruit.fruitId)
where (grocery.vegId = veggie.vegId)
select (grocery);
The problem I am facing is when Fruit and Vegetable objects are empty.
By empty, I mean their list count is 0 and I want to apply the filter only if the filter list is populated.
I am also NOT able to use something like since objects are null:
var groceryList = from grocery in Grocery.ToList()
from fruit in Fruit.ToList()
from veggie in Vegetable.ToList()
where (grocery.fruitId = fruit.fruitId || fruit.fruitId == String.Empty)
where (grocery.vegId = veggie.vegId || veggie.vegId == String.Empty)
select (grocery);
So, I intend to check for Fruit and Vegetable list count...and filter them as separate expressions on successively filtered Grocery objects.
But is there a way to still get the list in case of null objects in a single query expression?
I think the LINQ GroupJoin operator will help you here. It's similar to the TSQL LEFT OUTER JOIN
IEnumerable<Grocery> query = Grocery
if (Fruit != null)
{
query = query.Where(grocery =>
Fruit.Any(fruit => fruit.FruitId == grocery.FruitId));
}
if (Vegetable != null)
{
query = query.Where(grocery =>
Vegetable.Any(veggie => veggie.VegetableId == grocery.VegetableId));
}
List<Grocery> results = query.ToList();
Try something like the following:
var joined = grocery.Join(fruit, g => g.fruitId,
f => f.fruitId,
(g, f) => new Grocery() { /*set grocery properties*/ }).
Join(veggie, g => g.vegId,
v => v.vegId,
(g, v) => new Grocery() { /*set grocery properties*/ });
Where I have said set grocery properties you can set the properties of the grocery object from the g, f, v variables of the selector. Of interest will obviouly be setting g.fruitId = f.fruitId and g.vegeId = v.vegeId.
var groceryList =
from grocery in Grocery.ToList()
join fruit in Fruit.ToList()
on grocery.fruidId equals fruit.fruitId
into groceryFruits
join veggie in Vegetable.ToList()
on grocery.vegId equals veggie.vegId
into groceryVeggies
where ... // filter as needed
select new
{
Grocery = grocery,
GroceryFruits = groceryFruits,
GroceryVeggies = groceryVeggies
};
You have to use leftouter join (like TSQL) for this. below the query for the trick
private void test()
{
var grocery = new List<groceryy>() { new groceryy { fruitId = 1, vegid = 1, name = "s" }, new groceryy { fruitId = 2, vegid = 2, name = "a" }, new groceryy { fruitId = 3, vegid = 3, name = "h" } };
var fruit = new List<fruitt>() { new fruitt { fruitId = 1, fname = "s" }, new fruitt { fruitId = 2, fname = "a" } };
var veggie = new List<veggiee>() { new veggiee { vegid = 1, vname = "s" }, new veggiee { vegid = 2, vname = "a" } };
//var fruit= new List<fruitt>();
//var veggie = new List<veggiee>();
var result = from g in grocery
join f in fruit on g.fruitId equals f.fruitId into tempFruit
join v in veggie on g.vegid equals v.vegid into tempVegg
from joinedFruit in tempFruit.DefaultIfEmpty()
from joinedVegg in tempVegg.DefaultIfEmpty()
select new { g.fruitId, g.vegid, fname = ((joinedFruit == null) ? string.Empty : joinedFruit.fname), vname = ((joinedVegg == null) ? string.Empty : joinedVegg.vname) };
foreach (var outt in result)
Console.WriteLine(outt.fruitId + " " + outt.vegid + " " + outt.fname + " " + outt.vname);
}
public class groceryy
{
public int fruitId;
public int vegid;
public string name;
}
public class fruitt
{
public int fruitId;
public string fname;
}
public class veggiee
{
public int vegid;
public string vname;
}
EDIT:
this is the sample result
1 1 s s
2 2 a a
3 3