How to write a Strng.Join for this type of LINQ query(Lambda expression)? (var b will return number of integer lists)
1.
var b = braughtForwardInvoices
.Where(x => x.LinkedTransaction != null
&& x.LinkedTransaction.Count > 0)
.Select(x => x.LinkedTransaction.Select(x => x.TransactionId))
.ToList();
Below show the actual working query. I need to write the code in number 1 like number 2.
2.
var braughtForwardPaymentId =
from item in braughtForwardInvoices
where item.LinkedTransaction != null
&& item.LinkedTransaction.Count > 0
select string.Join(",", item.LinkedTransaction.Select(x => x.TransactionId)).ToString();
Take the list and send it to string.Join.
var b = braughtForwardInvoices.Where(x => x.LinkedTransaction != null
&& x.LinkedTransaction.Count > 0)
.Select(x => x.LinkedTransaction.Select(x => x.TransactionId))
.ToList();
var result = string.Join(",", b);
If you just need the selected IDs as a CSV string, you can join the resulting IEnumerable:
var b = string.Join(", ", braughtForwardInvoices.Where(x => x.LinkedTransaction != null
&& x.LinkedTransaction.Count > 0)
.Select(x => x.LinkedTransaction.Select(x => x.TransactionId)));
Related
if (model.ConnectedToOtherProfilesId != 0)
{
var fooGroup = fans.GroupBy(x => x.FanId)
.Where(x => x.Any(z => z.ProfileId == model.ConnectedToOtherProfilesId));
var fooGroup2 = fooGroup.Where(grp => grp.Count() > 1);
}
What I need is to put the results from fooGroup2 [IQueryable<IGrouping<int,PF>] into fans which is IQueryiable<PF>
Something like this:
fans = fooGroup2;
You could use a SelectMany.
//IQueryable<PF>
var fooGroup2 = fooGroup.Where(grp => grp.Count() > 1)
.SelectMany(pf => pf);
With the following code how would I join items together.
var shippedItems = _orderService.GetOrderById(shipment.OrderId).Shipments
.Where(x => x.ShippedDateUtc != null && x.OrderId == shipment.OrderId)
.Select(x => x.ShipmentItems)
.ToList();
So there may be two or more shipments for the order id.
Each shipment may contain identical items.
Need a nudge in the right direction
Have tried
var shippedItems = _orderService.GetOrderById(shipment.OrderId).Shipments
.Where(x => x.ShippedDateUtc != null && x.OrderId == shipment.OrderId)
.Select(x => x.ShipmentItems.Join(x.ShipmentItems
.Where(y => y.ShipmentId == shipment.Id)))
.ToList();
and
var shippedItems = _orderService.GetOrderById(shipment.OrderId).Shipments
.Where(x => x.ShippedDateUtc != null && x.OrderId == shipment.OrderId)
.Select(x => x.ShipmentItems.GroupBy(y => y.Id))
.ToList();
and
var shippedItems = _orderService.GetOrderById(shipment.OrderId).Shipments
.Where(x => x.ShippedDateUtc != null && x.OrderId == shipment.OrderId)
.Select(x => x.ShipmentItems.Distinct())
.ToList();
Here is the code I'm using for output the items:
foreach (var shipmentItem in shippedItems)
{
System.Diagnostics.Debug.WriteLine("item = " + shipmentItem);
System.Diagnostics.Debug.WriteLine("item = " + shipmentItem.OrderItemId);
}
The above output produces:
shippedItemsList count = 9 item =
System.Data.Entity.DynamicProxies.ShipmentItem_18BEAAFA747B42988EC4CB25D967298CC6736AF528389FC98E81143F7D629631
item = 356077
item = System.Data.Entity.DynamicProxies.ShipmentItem_18BEAAFA747B42988EC4CB25D967298CC6736AF528389FC98E81143F7D629631
item = 356078
item = System.Data.Entity.DynamicProxies.ShipmentItem_18BEAAFA747B42988EC4CB25D967298CC6736AF528389FC98E81143F7D629631
item = 356079
item = System.Data.Entity.DynamicProxies.ShipmentItem_18BEAAFA747B42988EC4CB25D967298CC6736AF528389FC98E81143F7D629631
item = 356077
item = System.Data.Entity.DynamicProxies.ShipmentItem_18BEAAFA747B42988EC4CB25D967298CC6736AF528389FC98E81143F7D629631
item = 356078
item =
System.Data.Entity.DynamicProxies.ShipmentItem_18BEAAFA747B42988EC4CB25D967298CC6736AF528389FC98E81143F7D629631
item = 356079
item =
System.Data.Entity.DynamicProxies.ShipmentItem_18BEAAFA747B42988EC4CB25D967298CC6736AF528389FC98E81143F7D629631
item = 356077
item = System.Data.Entity.DynamicProxies.ShipmentItem_18BEAAFA747B42988EC4CB25D967298CC6736AF528389FC98E81143F7D629631
item = 356079
item = System.Data.Entity.DynamicProxies.ShipmentItem_18BEAAFA747B42988EC4CB25D967298CC6736AF528389FC98E81143F7D629631
item = 356080
So the excepted output should be:
shippedItemsList count = 4
item = System.Data.Entity.DynamicProxies.ShipmentItem_18BEAAFA747B42988EC4CB25D967298CC6736AF528389FC98E81143F7D629631
item = 356077
item = System.Data.Entity.DynamicProxies.ShipmentItem_18BEAAFA747B42988EC4CB25D967298CC6736AF528389FC98E81143F7D629631
item = 356079
item = System.Data.Entity.DynamicProxies.ShipmentItem_18BEAAFA747B42988EC4CB25D967298CC6736AF528389FC98E81143F7D629631
item = 356078
item = System.Data.Entity.DynamicProxies.ShipmentItem_18BEAAFA747B42988EC4CB25D967298CC6736AF528389FC98E81143F7D629631
item = 356080
The above output is from using var shippedItems = _orderService.GetOrderById(shipment.OrderId).Shipments.Where(x => x.ShippedDateUtc != null && x.OrderId == shipment.OrderId).SelectMany(x => x.ShipmentItems).ToList();
NOTE: shipment item is ICollection<ShipmentItem> Shipment.ShipmentItems when I hover it in visual studio
UPDATED senario:
So let's say that the order has 3 items(a = 3, b= 5, c = 3), Now 1 shipment is sent with items(a = 1, b = 2, c = 0), Now a second shipment is sent with items(a = 1, b = 1, c = 1). I would like the quantity of items from both shipments. So I expect items(a = 2, b = 3, c = 1), I currently get items(a = 1, b = 2) + items(a = 1, b = 1, c = 1). So the list of shipment items I loop through are appearing more than once.
I thought maybe union but not sure how to put it together :/
UPDATE MY SOLUTION
I could not manage to accomplish this using lambda expression, so I
had to do the following solution to get the result I wanted. I hope
this helps others looking for workarounds.
//calculate quantity of total shipped items from each shipment
List<ShipmentItem> alreadyShippedItemsList = new List<ShipmentItem>();
Dictionary<int, int> alreadyShippedItems = new Dictionary<int, int>();
var shippedItems = _orderService.GetOrderById(shipment.OrderId).Shipments
.Where(x => x.ShippedDateUtc != null)
.SelectMany(x => x.ShipmentItems)
.ToList();
//create a list of shipment items
for (int i = 1; i <= shipmentsList.Count - 1; i++)
{
var si = shipmentsList[i];
var sii = si.ShipmentItems.ToList();
foreach (var item in sii)
{
var itemInList = alreadyShippedItemsList.Where(x => x.OrderItemId == item.OrderItemId).FirstOrDefault();
int sum = 0;
//create a list of shipment items and check for duplicate items
if (itemInList == null)
{
alreadyShippedItems.Add(item.OrderItemId, item.Quantity);
alreadyShippedItemsList.Add(item);
}
else
{
//if duplicate item is found update the quantity in the dictionary
sum = itemInList.Quantity + item.Quantity;
alreadyShippedItems[item.OrderItemId] = sum;
}
}
}
You need to use SelectMany, which flattens a list
var shippedItems = _orderService.GetOrderById(shipment.OrderId).Shipments
.Where(x => x.ShippedDateUtc != null && x.OrderId == shipment.OrderId)
.SelectMany(x => x.ShipmentItems)
.ToList();
You are using Distinct in the wrong place
var shippedItems = _orderService.GetOrderById(shipment.OrderId).Shipments
.Where(x => x.ShippedDateUtc != null && x.OrderId == shipment.OrderId)
.Select(x => x.ShipmentItems).Distinct()
.ToList();
Either override Equals function for the ShipmentItems class using this Correct way to override Equals() and GetHashCode() and use distinct directly or do two steps
var distinctShippedItemIds = _orderService.GetOrderById(shipment.OrderId).Shipments
.Where(x => x.ShippedDateUtc != null && x.OrderId == shipment.OrderId)
.Select(x => x.ShipmentItems.OrderItemId).Distinct()
.ToList();
List<ShippingItems> UniqueItemList=new List<ShippingItems>();
foreach(int OrderId in distinctShippedItemIds)
{
var shippedItems = _orderService.GetOrderById(shipment.OrderId).Shipments
.Where(x => x.ShippedDateUtc != null && x.OrderId == OrderId)
.Select(x => x.ShipmentItems).FirstOrDefault();
if(shippedItems !=null)
{
UniqueItemList.Add(shippedItems);
}
}
I may get you wrong but is this what you want?
SELECT * FROM [ShipmentItem]
INNER JOIN [Shipment] ON [ShipmentItem].[ShipmentId] = [Shipment].[Id]
WHERE [Shipment].[ShippedDateUtc] IS NOT NULL AND [Shipment].[OrderId] = #OrderId
So this will do the job
var shippedItems = _orderService.GetOrderById(orderId)
.Shipments
.Where(s => s.ShippedDateUtc != null)
.SelectMany(s => s.ShipmentItems)
.ToList();
Sample
Edit
If You you want to fetch the order items you have to do something like this
var orderItems = _orderService
.GetOrderById(orderId)
.Shipments
.Where(s => s.ShippedDateUtc != null)
.SelectMany(s => s.ShipmentItems)
.Select(si => _orderService.GetOrderItemById(si.OrderItemId))
.Distinct()
.ToList();
or if you want to produces less DB queries
var orderItems = _orderService
.GetOrderById(orderId)
.Shipments
.Where(s => s.ShippedDateUtc != null)
.SelectMany(s => s.ShipmentItems)
.Select(si => si.OrderItemId)
.Distinct()
.Select(id => _orderService.GetOrderItemById(id))
.ToList();
Edit 2
nopCommerce data of a order with 4 order items (quantity of 2) and 4 shipments
How can I write the follow query with Linq in C#?
SELECT MAX(A2.LINHA_PLANILHA)
FROM MD_IMP_FORCA_VENDA_DADOS_A2 A2
WHERE A2.LINHA <> '0'
AND TRIM(A2.SETORES) IS NOT NULL
AND A2.LINHA_PLANILHA <> 1
AND USUARIO = V_USUARIO
GROUP BY A2.LINHA, A2.BRICK
HAVING COUNT(A2.BRICK) > 1 AND COUNT(DISTINCT A2.SETORES) > 1;
I thought to do this:
var result = from r in dataTable.AsEnumerable()
where r.Field<string>(1) != "0"
&& r.Field<string>(2).Trim() != null
&& r.Field<Int32>(0) != 1
group r by new {Linha = r.Field<string>(1), Brick = r.Field<string>(3) } into temp
where temp.Count() > 1
select new { MaxLinha = (from r2 in temp select r2.Field<Int32>(0)).Max()};
But I don't know how to put the two COUNTS of HAVING clause in Linq query.
Any help would be appreciated.
Thanks
Zago
Perhaps:
var query = db.MD_IMP_FORCA_VENDA_DADOS_A2
.Where(x => x.LINHA != "0"
&& x.SETORES != null
&& x.SETORES.Trim() != ""
&& x.LINHA_PLANILHA <> 1
&& x.USUARIO = x.V_USUARIO
)
.GroupBy(x => new { x.LINHA, x.BRICK })
.Where(g => g.Count() > 1 && g.Select(x => x.SETORES).Distinct().Count() > 1)
.Select(g => g.Max(x => x.LINHA_PLANILHA));
I order two types of query. I want to show the result as one. if the first query and second query have count these both are merge and show the results of one. So i have created 3 list like jobs, jobs1, jobs2. I am getting values into jobs1 and jobs2. Then i have assigned using union into jobs3
Code
IQueryable<Job> jobs = _repository.GetJobs();
IQueryable<Job> jobs1 = _repository.GetJobs();
IQueryable<Job> jobs2 = _repository.GetJobs();
List<int> lstId = null;
List<int> lstUpdatedListId = null;
List<int> lstConId=null;
var order = _db.GetOrderDetails().Where(od => od.Masters.Id != null && od.OrderId == od.Master.OrderId && od.Master.Status == true && od.ValidityTill.Value >= currentdate).OrderByDescending(od => od.ValidityTill).Select(ord => ord.Master.Id.Value);
var order1 = _vasRepository.GetOrderDetails().Where(od => od.Masters.ConId != null && od.OrderId == od.Masters.OrderId && od.Masters.PaymentStatus == true && od.ValidityTill.Value >= currentdate).OrderByDescending(od => od.ValidityTill).Select(ord => ord.Masters.ConId.Value);
var updatedVacancyList = _repository.GetJobs().Where(c => c.UpdatedDate != null && updateFresh <= c.UpdatedDate).Select(c => c.Id);
if (order1 .Count() > 0)
{
lstConId = order1.ToList();
Func<IQueryable<Job>, IOrderedQueryable<Job>> orderingFunc = query =>
{
if (order1.Count() > 0)
return query.OrderByDescending(rslt => lstConId.Contains(rslt.Con.Id)).ThenByDescending(rslt=>rslt.CreatedDate);
else
return query.OrderByDescending(rslt => rslt.CreatedDate);
};
jobs1 = orderingFunc(jobs);
}
if (order.Count() > 0)
{
lstId = order.ToList();
lstUpdatedJobsListId = updatedVacancyList.ToList();
Func<IQueryable<Job>, IOrderedQueryable<Job>> orderingFunc = query =>
{
if (order.Count() > 0)
return query.OrderByDescending(rslt => lstId.Contains(rslt.Id)).ThenByDescending(rslt => lstUpdatedJobsListId.Contains(rslt.Id)).ThenByDescending(rslt=>rslt.CreatedDate);
if (updatedVacancyList.Count() > 0)
return query.OrderByDescending(rslt => lstUpdatedJobsListId.Contains(rslt.Id)).ThenByDescending(rslt => rslt.UpdatedDate);
else
return query.OrderByDescending(rslt => rslt.CreatedDate);
};
jobs2 = orderingFunc(jobs);
}
jobs = jobs1.Union(jobs2);
and i am getting an error while run the application as follows,
The text data type cannot be selected as DISTINCT because it is not comparable.
I need help to rectify this issue. I want to order in descending also.
One of your columns in Database is "Text" type. Convert it to varchar(MAX)
I have a list List<UserRoles> roles that has this structure
{r:1,u:1,v:3},
{r:1,u:1,v:5},
{r:2,u:1,v:9},
{r:3,u:2,v:10}
I am trying to write a LINQ statement that will filter out only the "r"s that have values 1 & 2 and return a collection of ints/strings of "v"s
This is what I am trying to do and my problem is in the part where I want to transform the into that holds only the corresponding "v"s.
List<Int32> = roles.Where(r => r.r == 1 || r.r == 2)
.Select(i => new Int32{id = i.v});
This doesn't compile with an error that 'id' is unknown.
the end result that I need is this:
List<Int32>
{v:3},
{v:5},
{v:9}
Sound like you need a list of int:
List<int> result = roles.Where(r => r.r == 1 || r.r == 2)
.Select(i => i.v)
.ToList();
In case you have a list of int to filter, you can use Contains method to avoid lots of ||:
var filters = new[] { 1, 2};
List<int> result = roles.Where(r => filters.Contains(r.r))
.Select(i => i.v)
.ToList();
Or maybe you need {v:9}, you can use anonymous type with var keyword:
var result = roles.Where(r => filters.Contains(r.r))
.Select(i => new { i.v })
.ToList();
I guess v is already an int.
So the solution would be as simple as :
var result = roles.Where(r => r.r == 1 || r.r == 2).Select(i => i.v).ToList();
If what you want is an array of anonymous objects, use this:
var res = roles.Where(r => r.r == 1 || r.r == 2).Select(i => new{i.v}).ToList();
This would produce a list of objects with a single property called v.
If you are looking for a list of integers, and v is an int in the original class, use this:
var res = roles.Where(r => r.r == 1 || r.r == 2).Select(i => i.v ).ToList();
// note that there's no new here ^^^^^
You've used an annoymous type but then added Int32 in front of it which is illegal.
List<Int32> results = roles.Where(r => r.r == 1 || r.r == 2)
.Select(i => new { i.v }).ToList();