I am trying to convert the following code into lambda style but without success.
DiscCurrentLocation[] old =
(from v in volumeDC.Volumes
join d in volumeDC.Disc_Vs
on v.VolumeID equals d.DiscVolumeID
group d by new { v.VolumeLibID, d.DiscCurrentLocation } into g
where (g.Key.VolumeLibID == libraryId && g.Key.DiscCurrentLocation > -1
&& g.Count() > 1)
select (DiscCurrentLocation)g.Key.DiscCurrentLocation
).ToArray<DiscCurrentLocation>();
Can somebody show me how to convert it?
Thanks
This should be identical:
DiscCurrentLocation[] old = volumeDC.Volumes
.Join(volumeDC.Disc_Vs, (v) => v.VolumeID, (d) => d.DiscVolumeID,
(v, d) => new { Volume = v, Disc_V = d })
.GroupBy(vd => new { vd.Volume.VolumeLibID, vd.Disc_V.DiscCurrentLocation })
.Where (grp => grp.Key.VolumeLibID == libraryId
&& grp.Key.DiscCurrentLocation > -1 && grp.Count() > 1)
.Select (grp => (DiscCurrentLocation)grp.Key.DiscCurrentLocation)
.ToArray<DiscCurrentLocation>()
;
Related
I've this linq query:
var query = (from l in _contexto.lineasencargos
join a in _contexto.articulos on l.IDARTICULO equals a.IDARTICULO
join af in _contexto.articulofamilia on a.IDARTICULO equals af.IDARTICULO
join f in _contexto.familias on af.IDFAMILIA equals f.IDFAMILIA
join e in _contexto.encargos on l.IDENCARGO equals e.IDENCARGO
where e.FECHAHORAENCARGOS >= _finder.FechaDe &&
e.FECHAHORAENCARGOS <= _finder.FechaA &&
e.FECHAHORARECOGERENCARGOS >= _finder.FechaRecogerDe &&
e.FECHAHORARECOGERENCARGOS <= _finder.FechaRecogerA &&
e.clientes.RAZONSOCIALCLIENTE.Contains(_finder.Cliente)
group l by new { l.IDARTICULO, l.CANTIDADLINEAENCARGO,a.DESCRIPCIONARTICULO,f.DESCRIPCION,f.IDFAMILIA }
into g
select new listaEncargosAgrupados
{
IdArticulo=(int)g.Key.IDARTICULO,
DescripcionArticulo=g.Key.DESCRIPCIONARTICULO,
IdFamilia=g.Key.IDFAMILIA,
DescripcionFamilia=g.Key.DESCRIPCION,
SumaCantidad = (decimal)g.Sum(x => x.CANTIDADLINEAENCARGO),
SumaPrecio = (decimal)g.Sum(x => x.PRECIOLINEAENCARGO),
Total = (decimal)((decimal)g.Sum(x => x.CANTIDADLINEAENCARGO) * g.Sum(x => x.PRECIOLINEAENCARGO))
});
and i need create a condition in Where, that filter dynamically:
if (_finder.IdTienda > 0)
{
query = query.Where(x=>x.IDTIENDA == _finder.IdTienda);
}
But this Where it is not correct because IDTIENDA is contained in _context.encargos and not in listaEncargosAgrupados
How i can revolve this problem?
Thanks
Add e into grouping statement and IDTIENDA list into the result:
var query = (from l in _contexto.lineasencargos
join a in _contexto.articulos on l.IDARTICULO equals a.IDARTICULO
join af in _contexto.articulofamilia on a.IDARTICULO equals af.IDARTICULO
join f in _contexto.familias on af.IDFAMILIA equals f.IDFAMILIA
join e in _contexto.encargos on l.IDENCARGO equals e.IDENCARGO
where e.FECHAHORAENCARGOS >= _finder.FechaDe &&
e.FECHAHORAENCARGOS <= _finder.FechaA &&
e.FECHAHORARECOGERENCARGOS >= _finder.FechaRecogerDe &&
e.FECHAHORARECOGERENCARGOS <= _finder.FechaRecogerA &&
e.clientes.RAZONSOCIALCLIENTE.Contains(_finder.Cliente)
group new { l, e} by new { l.IDARTICULO, l.CANTIDADLINEAENCARGO,a.DESCRIPCIONARTICULO,f.DESCRIPCION,f.IDFAMILIA }
into g
select new { Result = new listaEncargosAgrupados
{
IdArticulo=(int)g.Key.IDARTICULO,
DescripcionArticulo=g.Key.DESCRIPCIONARTICULO,
IdFamilia=g.Key.IDFAMILIA,
DescripcionFamilia=g.Key.DESCRIPCION,
SumaCantidad = (decimal)g.Sum(x => x.l.CANTIDADLINEAENCARGO),
SumaPrecio = (decimal)g.Sum(x => x.l.PRECIOLINEAENCARGO),
Total = (decimal)((decimal)g.Sum(x => x.l.CANTIDADLINEAENCARGO) * g.Sum(x => x.l.PRECIOLINEAENCARGO))
},
IDTIENDAs = new HashSet<int>(from x in g
let id = x.e.IDTIENDA
where id.HasValue
select (int)id.Value)
});
...
if (_finder.IdTienda > 0)
{
query = query.Where(x => x.IDTIENDAs.Contains (_finder.IdTienda));
}
var query1 = query.Select(x => x.Result);
Finally the solution to my problem was to employ executestorequery in the context of my EF, and creat a SQL query :
List<ListaEncargosAgrupados> lista;
string queryString = #"SELECT l.IDARTICULO,a.DESCRIPCIONARTICULO,f.DESCRIPCION descripcionFamilia,f.IDFAMILIA,sum(l.CANTIDADLINEAENCARGO) sumaCantidad,avg(l.PRECIOLINEAENCARGO)
sumaPrecio,sum(l.CANTIDADLINEAENCARGO)*avg(l.PRECIOLINEAENCARGO) Total " +
"FROM lineasencargos l,articulos a,articulofamilia af,familias f,encargos e " +
"where a.IDARTICULO=l.IDARTICULO and a.IDARTICULO=af.IDARTICULO " +
"and af.IDFAMILIA=f.IDFAMILIA and l.IDENCARGO=e.IDENCARGO ";
if (_finder.IdTienda > 0)
{
queryString = queryString + " and e.idtienda=" + _finder.IdTienda;
}
queryString = queryString + " group by l.IDARTICULO,a.DESCRIPCIONARTICULO,f.DESCRIPCION,f.IDFAMILIA order by a.DESCRIPCIONARTICULO ";
var salidaQuery = _contexto.ExecuteStoreQuery<ListaEncargosAgrupados>(queryString).AsQueryable().ToList();
lista = salidaQuery;
my below query looks ok to me but im not sure why im getting errors.
The error is "the best overload for string.containts(string) has some invalid arguments". what am i missing here?
Thanks
string[] strHiddenESXi = {"Internal","Support","Archived"};
var tblvirtualservers = from d in db.tblVirtualServers.Include(t => t.ChangeLog).Include(t => t.ESXi)
where (!d.ESXi.ESXiName.Contains(strHiddenESXi)) && d.ESXiID != 20
string[] strHiddenESXi = {"Internal","Support","Archived"};
var tblvirtualservers = from d in db.tblVirtualServers.Include(t => t.ChangeLog)
.Include(t => t.ESXi)
where (!strHiddenESXi.Contains(d.ESXi.ESXiName)) && d.ESXiID != 20
You have to use Contains with strHiddenESXi that is an Array.
Can you try?
string[] strHiddenESXi = {"Internal","Support","Archived"};
var tblvirtualservers = from d in db.tblVirtualServers.Include(t => t.ChangeLog)
.Include(t => t.ESXi)
where (!strHiddenESXi.Any( a=> d.ESXi.ESXiName.Contains(a) )) && d.ESXiID != 20
This code works ok, but I was wondering whether there isn't some way to write it in one LINQ expression so a single pass can be done by the database server instead of realising a result set and then looping through it, which is what my code will produce.
var logs = from AssetLog log in dc.AssetLogs
where log.AssetId == assetId && log.Recorded >= start && log.Recorded <= finish
select log;
return new GetInteractionBoundsResult()
{
N = logs.Max(log => log.Latitude),
S = logs.Min(log => log.Latitude),
W = logs.Min(log => log.Longitude),
E = logs.Max(log => log.Longitude)
};
So, LINQ gurus, how would you write the above so that it produces more or less this at the database:
SELECT MIN(Latitude) S, MAX(Latitude) N, MIN(Longitude) W, MAX(Longitude) E
FROM ASSETLOG WHERE etc etc
Sure, just trick your LINQ provider into thinking it's still working with a query until the very end:
var logs = from asset in dc.Assets
where asset.AssetId == assetId
let g = asset.AssetLogs
.Where(log => log.Recorded >= start && log.Recorded <= finish)
select new GetInteractionBoundsResult
{
N = g.Max(log => log.Latitude),
S = g.Min(log => log.Latitude),
W = g.Min(log => log.Longitude),
E = g.Max(log => log.Longitude)
};
return logs.Single();
A Group By may perform better than the join that the above query would produce:
var logs = from log in dc.AssetLogs
where log.AssetId == assetId &&
log.Recorded >= start && log.Recorded <= finish
group log by log.AssetId into g
select new GetInteractionBoundsResult
{
N = g.Max(log => log.Latitude),
S = g.Min(log => log.Latitude),
W = g.Min(log => log.Longitude),
E = g.Max(log => log.Longitude)
};
return logs.Single();
It would take a pretty sophisticated LINQ provider, but a subquery may work:
var res = from asset in dc.Assets
where log.AssetId == assetId
let logs = (from AssetLog log in asset.AssetLogs
where log.Recorded >= start && log.Recorded <= finish
select log)
select new GetInteractionBoundsResult()
{
N = logs.Max(log => log.Latitude),
S = logs.Min(log => log.Latitude),
W = logs.Min(log => log.Longitude),
E = logs.Max(log => log.Longitude)
};
return res.Single();
List<Product> Prs = data.Products
.Where(x=> x.ProductColors
.Where(y=> y.Color=="blue")
.Select(z=> z.ProductID)
.Contains(x.ID) && x.ProductColors
.Where(y=> y.Color== "red")
.Select(z=> z.ProductID)
.Contains(x.ID))
.ToList();
How to PredicateBuilder multi-criteria?
Something like the following:
var inner = PredicateBuilder.False<Product>();
inner = inner.Or (p => p.Description.Contains ("foo"));
inner = inner.Or (p => p.Description.Contains ("far"));
var outer = PredicateBuilder.True<Product>();
outer = outer.And (p => p.Price > 100);
outer = outer.And (p => p.Price < 1000);
outer = outer.And (inner);
var results = data.Products.AsExpandable().Where(outer)
You can read more about PredicateBuilder here
how can we add a where condition to a linq subselect query.
i.e.
List<CallLog> callLog = CallLog.SampleData();
List<Contacts> contacts = Contacts.SampleData();
var q = from call in callLog
where call.Incoming == true
group call by call.Number into g
select new contacts {
contact.FirstName = g.FirstName,
contact.LastName = g.LastName,
Count = g.Count(),
Avg = g.Average( c => c.Duration ) <--- WHERE c.Duration > 5,
Total = g.Sum( c => c.Duration ) <--- WHERE c.Duration >= 60
};
How can we add a "Where condition" to the LINQ statement as shown above?
Simply add a Where method with the clause you described!
Avg = g.Where(c => c.Duration > 5).Average(c => c.Duration),
Total = g.Where(c => c.Duration >= 60).Sum(c => c.Duration)
You almost had it:
var q = from call in callLog
where call.Incoming == true
group call by call.Number into g
select new contacts {
contact.FirstName = g.FirstName,
contact.LastName = g.LastName,
Count = g.Count(),
Avg = g.Where(c => c.Duration > 5).Average( c => c.Duration ),
Total = g.Where(c => c.Duration >= 60).Sum( c => c.Duration )
};