Extract values from IEnumerable variable - asp.net

InfowareEntities Infoware = new InfowareEntities();
IEnumerable admn = Infoware.Admissions.Where(x => x.AdmissionNo == 1520002);
In my admission database table I have columns- admissionNo, firstname, lastname...
now from above lambda expression I need to get firstname.
Please help me with this.

Try chaining a select like this
.Where(x => x.AdmissionNo == 15200).select (n => n.FirstName)
to get a list of names.

I believe you need this,
InfowareEntities Infoware = new InfowareEntities();
IEnumerable admn = Infoware.Admissions.Where(x => x.AdmissionNo == 1520002);
var arrayOfFirstNames = admn.select(n => n.FirstName).ToArray();
You can also use "ToList();" if you want list of first names..

Related

Get minimum value from list

I have a class ABC like this
public class ABC{
public int Id {get;set;}
public int UserCount {get;set;}
}
Now I add following records to a list of type ABC
List<ABC> lstABC = new List<ABC>();
lstABC.Add(new ABC(){Id=1,UserCount=5});
lstABC.Add(new ABC(){Id=2,UserCount=15});
lstABC.Add(new ABC(){Id=3,UserCount=3});
lstABC.Add(new ABC(){Id=4,UserCount=20});
I've another list of type int
List<int> lstIds = new List<int>();
lstIds.Add(1);
lstIds.Add(3);
lstIds.Add(4);
Now i want to find out the minimum value of UserCount by comparing both the list where Id in lstABC should match the items presesnt in lstIds. I can get the minimum value of UserCount by using loops but is there any another way to get the value in an optimized way by avoiding loops?
You can use Enumerable.Join to link both lists:
var joined = from id in lstIds
join x in lstABC
on id equals x.Id
select x;
int minValue = joined.Min(x => x.UserCount);
This is more efficient than loops since Join uses a set to find matching items.
There's more than one way to skin a cat, this is a little bit less efficient:
int minValue = lstABC.Where(x => lstIds.Contains(x.ID)).Min(x => x.UserCount);
Try below code:
int min = lstABC.Min(entry => entry.UserCount);
var a = lstABC.Where(e => e.UserCount == min).FirstOrDefault();
var resul = lstIds.Where(e => e.Equals(a.Id)).FirstOrDefault();
var result = lstABC.Where(n =>n.Id == resul).FirstOrDefault();

linq sum and group [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Dynamic Anonymous type in Razor causes RuntimeBinderException
I have this Linq Agregate Query
var GruposQ = from lcGrupos in db.Merlin_ConceptosFacturacion_Kit_Componentes
where lcGrupos.NumIdConcepto == Item.NumIdConcepto & lcGrupos.BitComponenteVariable == true
select lcGrupos;
var GruposList = from comps in GruposQ
group comps by
new
{
NumIdGrupoProducto = comps.NumIdGrupoProducto,
} into g
select new
{
NumIdTransaccion = NumIdTransaccion,
NumIdGrupoProducto = g.Key.NumIdGrupoProducto,
NumCantidad = g.Sum(x=>x.NumCantidad),
Grupo = GruposQ.Where(x => x.NumIdGrupoProducto == g.Key.NumIdGrupoProducto)
};
ViewBag.CompsKit = GruposList.ToList();
My problem is when I try to get elements from ViewBag.CompsKit:
#foreach (var myTrans in ViewBag.CompsKit)
{
// Here it throws an error
// 'object' does not contain a definition for 'NumIdtransaccion'
<span>myTrans.NumIdtransaccion</span>
}
But if i look into this object it allready has the property.
myTrans { NumIdTransaccion = 15460
, NumIdGrupoProducto = 163
, NumCantidad = 100,000
, Grupo = System.Data.Common.Internal.Materialization.CompensatingCollection`1[ParadigmaNet.Areas.Items.Models.Merlin_ConceptosFacturacion_Kit_Componentes] } dynamic {<>f__AnonymousType7<decimal,decimal?,decimal,System.Linq.IQueryable<ParadigmaNet.Areas.Items.Models.Merlin_ConceptosFacturacion_Kit_Componentes>>}
How can I do to access the properties ? in this agregate ?
You can't use "dynamic" type in a Razor View.
You must use a typed object as Model.
You can do grouping and filtering in single query:
var numIdConcepto = Item.NumIdConcepto;
var query = from comps in db.Merlin_ConceptosFacturacion_Kit_Componentes
where comps.NumIdConcepto == numIdConcepto &&
comps.BitComponenteVariable
group comps by comps.NumIdGrupoProducto into g
select new
{
NumIdGrupoProducto = g.Key,
NumCantidad = g.Sum(x => x.NumCantidad),
Grupo = g.ToList()
};
ViewBag.CompsKit = query.ToList();
ViewBag.NumIdTransaccion = NumIdTransaccion;
Also
you don't need create anonymous object for grouping by single property
you don't need to compare boolean values with true/false
you can simply use g.Key when use single property for grouping
items in group already will have NumIdGrupoProducto equal to grouping key
Instead of assigning same NumIdTransaccion to each group in the query result, pass that value to view separately: ViewBag.NumIdTransaccion = NumIdTransaccion
View:
<span>ViewBag.NumIdTransaccion</span>
#foreach(var item in ViewBag.CompsKit)
{
<span>#item.NumIdGrupoProducto</span>
<span>#item.NumCantidad</span>
}
Consider also creating ViewModel for this view - thus you will be safe about typos and all such errors will be eliminated at compile time.

How to calculate count on of table column using group by clause in linq

I'm new to linq.
In c# I'm doing as follows to get the count of one column.
SELECT DispatcherName,
ActivityType,
CONVERT(BIGINT,COUNT(ActivityType)) AS Total
FROM ACTIVITYLOG
GROUP BY DispatcherName,
ActivityType
ORDER BY Total DESC
Can any one tell m,how I can achieve the same thing using LINQ.
Update:
HI I did as follows and got the reslut.
But I'm not able to convert result to datatable.
this is how I did.
here dt is datatabe with two columns Dispatchername and ActivityType.
var query1 = from p in dt.AsEnumerable()
group p by new
{
DispatcherName = p.Field<string>("Dispatchername"),
Activity = p.Field<string>("ActivityType"),
}
into pgroup
let count = pgroup.Count()
orderby count
select new
{
Count = count,
DispatcherName = pgroup.Key.DispatcherName,
Activity = pgroup.Key.Activity
};
pls help me out asap.
from c in ACTIVITYLOG
group c by new {c.DispatcherName, c.ActivityType} into g
orderby g.Count() descending
select new { g.Key.DispatcherName, g.Key.ActivityType, Total = g.Count() }
If you want your results returned back to a DataTable, one option is to use the CopyToDataTable method.
Here's a live example: http://rextester.com/XHX48973
This method basically requires you to create a dummy table in order to use its NewRow method - the only way to create a DataRow, which is required by CopyToDataTable.
var result = dt.AsEnumerable()
.GroupBy(p => new {
DispatcherName = p.Field<string>("DispatcherName"),
Activity = p.Field<string>("ActivityType")})
.Select(p => {
var row = dummy.NewRow();
row["Activity"] = p.Key.Activity;
row["DispatcherName"] = p.Key.DispatcherName;
row["Count"] = p.Count();
return row;
})
.CopyToDataTable();
Perhaps a better way might be just fill in the rows directly, by converting to a List<T> and then using ForEach.
DataTable dummy = new DataTable();
dummy.Columns.Add("DispatcherName",typeof(string));
dummy.Columns.Add("Activity",typeof(string));
dummy.Columns.Add("Count",typeof(int));
dt.AsEnumerable()
.GroupBy(p => new { DispatcherName = p.Field<string>("DispatcherName"),
Activity = p.Field<string>("ActivityType")})
.ToList()
.ForEach(p => {
var row = dummy.NewRow();
row["Activity"] = p.Key.Activity;
row["DispatcherName"] = p.Key.DispatcherName;
row["Count"] = p.Count();
dummy.Rows.Add(row);
});
Live example: http://rextester.com/TFZNEO48009
This should do the trick:
IList<ACTIVITYLOG> allActivityLogs;
var result = (from c in allActivityLogs
select new
{
DispatcherName = c.DispatcherName,
ActivityType = c.ActivityType,
Total = c.ActivityType.Count
}).OrderByDescending(x => x.Total)
.GroupBy(x => new { x.DispatcherName, x.ActivityType });
You only need to substitute the allActivityLogs collection with the actual collection of your entities.

Entity Framework query syntax

I having a trouble with a query
I need to take out the SHIPMENT from GetAllOrderData - the same place where you can find POD_DATE and RECEIVE_NAME...but I get an error
Error 1 The name 'x' does not exist in the current context
My code is:
public IEnumerable<ReportItemDTO> GetTaskProgress(DateTime targetDate)
{
try
{
var startDate = targetDate.Date;
var endDate = startDate.AddDays(1);
OrderDataRepository rep = new OrderDataRepository();
var query = rep.GetAllOrderData()
.Where(x => x.POD_DATE >= startDate && x.POD_DATE <= endDate)
.GroupBy(o => o.User)
.Select(g => new ReportItemDTO
{
DriverId = g.Key.Id,
PdriverName = g.Key.Name,
OrderCount = g.Count(),
ReportedOrdersCount = g.Count(o => o.RECEIVE_NAME != null),
SHIPMENT = (x.SHIPMENT)
} );
return query;
SHIPMENT = (x.SHIPMENT)
Well you are within a grouping when you try to make that assignment - there are many shipments in each grouping not just one - in fact all shipments for that particular user. Assuming you want a collection of them you could do:
Shipments = g.Select( x=> x.SHIPMENT)
Edit:
If you just want the first shipment for each user (somewhat illogical but fits your data model):
SHIPMENT = g.Select( x=> x.SHIPMENT).First()

Dynamic Linq for dates

I want to build dynamic Linq. Following is my code which works fine for one date. But user can select many dates from calendar. And I need to make Linq for all those selected dates.
saleDate = calendarSales.SelectedDate;
List<SaleDetails> saleDetials = new List<SaleDetails>();
saleDetials = GetSaleDetails();
saleDetials.Where(sale => (Convert.ToDateTime(sale.DATE_TIME).Day == saleDate.Day &&
Convert.ToDateTime(sale.DATE_TIME).Month == saleDate.Month &&
Convert.ToDateTime(sale.DATE_TIME).Year == saleDate.Year)
).ToList();
How to update this query?
You have to build the predicate for your where clause dynamically.
Take a look at the predicatebuilder.
EDIT
Of cause PredicateBuilder supports AND and OR operators.
When using OR you have to start with the initial value of False:
// building the predicate
var pred = PredicateBuilder.False<SaleDetails>();
foreach (var date in MyDateList)
{
pred = pred.Or(sale => sale.DATE_TIME.Date == saleDate.Date);
}
// finally get the data and filter it by our dynamic predicate
List<SaleDetails> saleDetails = GetSaleDetails().Where(pred).ToList();
I'm not sure you need dynamic LINQ here. You should be able to check Where the sale matches Any of the selected dates, like so:
var saleDates = GetSelectedDate();
List<SaleDetails> saleDetials = new List<SaleDetails>();
saleDetials = GetSaleDetails();
saleDetials.Where(sale => saleDates.Any(date =>
(Convert.ToDateTime(sale.DATE_TIME).Day == date.Day &&
Convert.ToDateTime(sale.DATE_TIME).Month == date.Month &&
Convert.ToDateTime(sale.DATE_TIME).Year == date.Year)
)).ToList();
or checking on the Date property:
var saleDates = GetSelectedDate();
List<SaleDetails> saleDetials = new List<SaleDetails>();
saleDetials = GetSaleDetails();
saleDetials.Where(sale => saleDates.Any(date =>
Convert.ToDateTime(sale.DATE_TIME).Date == date.Date)).ToList();

Resources