where does not contain array - linq

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

Related

I have a section of LINQ that I need to compare

var myArray = ["A3|001", "A2|002", "A1|003"];
string myValue = "A2";
var No_NewList = myArray.Where(r => r.Contains(myValue.ToUpper())).ToList();
But this is not the result I want
I want the result to be A2|002
How about:
var No_NewList = myArray
.Where(s => myValue.Equals(s.Split('|')[0]))
.FirstOrDefault();

Finding bounds with LINQ

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();

How to use GroupBy in lambda?

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>()
;

Foreach implementation on splitting a string into array and filling into a list

I have a string of email addresses something like :
string str = abc#gmail.com;ghf < ghf#gmail.com >;xyz < xyz#gmail.com>
Now i wanna do something like this
List<string> test = new List<string>();
Regex.Split(to, ";").ToList().ForEach(x => x.Split(new char[] { '<', '>' }).Select(y => y != "<" || y != ">"));
Now how do i Fill only email addresses like abc#gmail.com , ghf#gmail.com and xyz#gmail.com into the list test in single linq query ?
var result = str.Split(';')
.Select(m => Regex.Replace(m, "([^<]+)<([^>]+)>", "$2")
.Trim()).ToList();
Did you try something like:
var test = Regex.Split(to, ";").ToList().ForEach(x => x.Split(new char[] { '<', '>' }).Select(y => y != "<" || y != ">"));

LINQ: Build a where clause at runtime to include ORs ( || )?

I need to build a where clause at runtime but I need to do an OR with the where clause. Is this possible?
Here is my code. Basically "filter" is a enum Bitwise, son hence filter could be equal to more than 1 of the following. Hence I need to build up the where clause.
If I execute the WHEREs separately then imagine if I do the Untested first, and it returns 0 records that means I can't execute a where on the Tested because its now 0 records.
I will put some pseudo-code below:
string myWhere = "";
if ((filter & Filters.Tested) == Filters.Tested)
{
if (myWhere != "" ) myWhere =myWhere + "||";
myWhere = myWhere " Status == "Tested";
}
if ((filter & Filters.Untested) == Filters.Untested)
{
if (myWhere != "" ) myWhere =myWhere + "||";
myWhere = myWhere " Status == "Untested";
}
if ((filter & Filters.Failed) == Filters.Failed)
{
if (myWhere != "" ) myWhere =myWhere + "||";
myWhere = myWhere " Status == "Failed";
}
// dataApplications = a List of items that include Tested,Failed and Untested.
// dataApplication.Where ( myWhere) --- Confused here!
Is this possible?
I don't want to include lots of "IFs" because there are lots of combinations i.e. no filter, filter= tested Only, filter = Untested and Tested ... and lots more.
If you have this:
IEnumerable<MyType> res = from p in myquery select p;
You can define a
var conditions = new List<Func<MyType, bool>>();
conditions.Add(p => p.PropertyOne == 1);
conditions.Add(p => p.PropertyTwo == 2);
res = res.Where(p => conditions.Any(q => q(p)));
And now the trick to make Lists of Funcs of anonymous objects (and you can easily change it to "extract" the type of anonymous objects)
static List<Func<T, bool>> MakeList<T>(IEnumerable<T> elements)
{
return new List<Func<T, bool>>();
}
You call it by passing the result of a LINQ query. So
var res = from p in elements select new { Id = p.Id, Val = p.Value };
var conditions = MakeList(res);
var statusTexts = new List<string>(); // Add desired status texts
dataApplication.Where(item =>
statusTexts.Any(status => item.Status == status))
Use HashSet<> for statuses, then .Contains will be O(1) instead of usual O(n) for List<>:
var statuses = new HashSet<string>() {"a", "b", "c"};
var list = new[] {
new { Id = 1, status = "a"},
new { Id = 2, status = "b"},
new { Id = 3, status = "z"}
};
var filtered = list.Where(l => statuses.Contains(s => l.status == s));

Resources