Compare list elements with string - c#

I have a list of db table type I want to access list elements and compare with string but I cannot access list elements How to do it?
List<Tbl_UserCustomField> customattribute = (from custom in tniDataContext.Tbl_UserCustomFields
where workOrderIndex.LoginId == custom.LoginId
select custom).ToList();
After executing the query and storing the query result in list the customattribute is only returning count of elements in list but i want elements in string

Access it like:
foreach(var item in customattribute)
{
if(item.SomeField == "someString")
DoSomething();
else
DoSomethingElse();
}
If the varchar column is all you want then you can directly select it:
var customattribute = (from custom in tniDataContext.Tbl_UserCustomFields
where workOrderIndex.LoginId == custom.LoginId
select custom.SomeColumn).ToList();
foreach(var item in customattribute)
{
if(item == "someString")
DoSomething();
else
DoSomethingElse();
}

Try customattribute.ForEach(i => Console.Write("{0}\t", i)); and see what is showing on console?

If you know the column or property in Tbl_UserCustomField class which holds the string you are looking for, iterate through the customattribute and fetch the string. Basically, you will have to capture such result in a variable of type List<string>. This can be done in a plain foreach-way OR using a Select Linq expression that just retrieves the column you specify
// Approach 1:
List<string> customAttributeValues = customattribute.Select(c => c.YourStringFieldName).ToList();
// Approach 2:
List<string> customAttributeValues = new List<string>();
foreach (var custom in customattribute)
{
customAttributeValues.Add(custom.YourStringFieldName);
}

Related

Foreach with where clause when reading from a Sharepoint List

I am trying to filter a result set which I read from a Sharepoint(list). I have to filter records that have a user specified and sadly user column of the list is a lookup column and gets the actual username from another list.
Normally,I can get the username value of a record (if it has any) like this:
foreach (var item in listItems)
{
if (item.FieldValues.TryGetValue("nqhs", out var userLookup))
{
if (userLookup != null && userLookup.ToString() == "Microsoft.SharePoint.Client.FieldUserValue")
{
var theUser = ((FieldLookupValue)item["nqhs"]).LookupValue; //this returns theUser = "John Doe"
}
}
}
nqhs is the name of the column which holds the Username in the Sharepoint list.
Is there any way I can apply this logic to a where clause in foreach, so that I can work with a much smaller result set?
I am trying something like this but I can't get it to work:
foreach (var item in listItems.Where(p => p.((FieldLookupValue)p["nqhs"]).LookupValue == "John Doe"))
Also tried this and get and "object reference not set to an instance of an object" error...
foreach (var item in from item in listItems where ((FieldLookupValue)item["nqhs"]).LookupValue == "John Doe" select item)
Try filtering the lookup list first, and then use the filtered list in you foreach
var filteredList = listItems.Where(p => p.((FieldLookupValue)p["nqhs"]);
foreach(var item in filteredList)
Some queries to SP require an execution to return results before they can be used. It's also better for performance because the Where clause in your current loop will execute with each iteration.

Filter a collection column by multiple values

I have a collection and I would like to filter it with one of the column contains multiple values. The filter values are dynamically generated and I dont know how many I will get.
I tried the following without success:
var input = #"was.Name.Contains(""Test"") || was.Name.Contains(""Test2"")";
var test = collection.Where(was => input)).ToList();
Assuming you receive the filter values as a CSV string:
var csvFilters = "Test1, Test2";
// split by ',', remove empty entries,
// trim each filter and store the result in a list
var filters = csvFilters.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(x => x.Trim())
.ToList();
// return items in collection whose Name property
// is equal to any of the items in filters
var result = collection.Where(x => filters.Contains(x.Name)).ToList();
This should translate to the following SQL:
SELECT * FROM collection c
WHERE c.Name IN ('Test1', 'Test2')
I guess you want to use LINQ. The question is, how the "filter" values are kept? I'll answer in the way I understand your question.
If input is supposed to be a condition then I'd suggest using Func<Object,bool>. This means, the input would be the condition you're looking for, and if found, it would return true.
Here is a simple example:
IEnumerable <T> FindElements (Func<Object, bool> condition, IEnumerable<T> inputList)
{
List<T> outputList = new List<T>();
foreach(var element in inputList)
{
if(condition != null && condition(element))
outputList.Add(element);
}
return outputList;
}
Then, if you call the function given exemplary parameters:
string input[] = {"Test1","Test2"};
foreach(string s in input)
{
targetList = FindElements(element=>((cast)element).Name.Contains(s), collection);
}
You should get all elements in collection which name has Test1 or Test2. Cast is of course name of the class which element instantiates.

How to get values out of IGrouping?

I have applied IGrouping<> over a list - here's what it looks like:
IEnumerable<IGrouping<TierRequest,PingtreeNode>> Tiers
{
get { return ActiveNodes.GroupBy(x => new TierRequest(x.TierID, x.TierTimeout, x.TierMaxRequests)); }
}
Later in my code I iterate over Tiers. Its simple to get the key data using the Key element, but how do I get the IEnumerable<PingtreeNode> that forms the value part?
Thanks in advance
Tiers.Select(group => group.Select(element => ...));
in foreach you can get values like this
foreach(var group in tiers)
{
TierRequest key = group.Key;
PingtreeNode[] values = group.ToArray();
}
The group itself implements IEnumerable<T> and can be iterated over, or used with linq methods.
var firstGroup = Tiers.First();
foreach(var item in firstGroup)
{
item.DoSomething();
}
// or using linq:
firstGroup.Select(item => item.ToString());
// or if you want to iterate over all items at once (kind of unwinds
// the grouping):
var itemNames = Tiers.SelectMany(g => g.ToString()).ToList();

Assigning the result of group by to items in a list with linq

I have an
IEnumerable<typeA> result;
from this result I need to get sum group by some id.
So I have the query
var groupeddata = from data in result
group data by data.Title
into grouped
select new { intid= grouped.Key,
expsum= grouped.Sum(x=>x.expnum)};
now this expsum I need to assign to the items of result where typeA.id is same as intid. Now how to do this assignment?
The simplest approach would probably be to use a dictionary:
var sumDictionary = query.ToDictionary(pair => pair.intid, pair => pair.expsum);
foreach (var item in result)
{
// We don't know which property you actually want to assign to
item.Sum = sumDictionary[item.id];
}

Retrieving values from a Linq GroupBy

I have a datatable which contains a load of dates. I wanted to group these by date and give each row a count.
I have managed to do this by dong the following:
IEnumerable query = from row in stats.AsEnumerable()
group row by row.Field<string>("date") into grp
select new { Date = grp.Key, Count = grp.Count(t => t["date"] != null) };
(where "stats" is the datatable)
I can see from debugging that this brings back the values all grouped as I need, but now I need to loop them and get each date and count.
My problem is I don't know how to retrieve the values!
I have a foreach loop
foreach (var rw in query)
{
string date = rw.Date; // <---- this is my problem?
}
I don't know what type my Ienumerable is to be able to reference the values in it!
So my question is how can I retrieve each date and count for each row by doing similar to the above?
I hope this makes sense!
This link on my blog should help you
http://www.matlus.com/linq-group-by-finding-duplicates/
Essentially your type is an anonymous type so you can't reference it as a type but you can access the properties like you're trying to do.
I think I see your issue. If you're trying to return it from a method, you should define a type and reuturn it like shown below:
public IEnumerable<MyType> GetQuery()
{
var query = from row in stats.AsEnumerable()
group row by row.Field<string>("date") into grp
select new { Date = grp.Key, Count = grp.Count(t => t["date"] != null) };
foreach (var rw in query)
{
yield return new MyType(rw.Date, rw.Count);
}
}
declare your "query" variable using "var" as shown above.
I guess you don't have access to the properties of the anonymous class because you're using IEnumerable query = .... Try var query = ... instead.
Going by your comment "I am returning the query from a function", which I take to mean that you want to do the query in a method, return the data to the caller, and then iterate the data in the caller, I suggest you return a Dictionary<DateTime, int>, like this:
static Dictionary<DateTime, int> GetSummarisedData()
{
var results = (
from row in stats.AsEnumerable()
group row by row.Field<string>("date") into grp
select new { Date = grp.Key, Count = grp.Count(t => t["date"] != null) })
.ToDictionary(val => val.Date, val => val.Count);
return results;
}
then in the caller you can just
foreach (var kvp in GetSummarisedData())
{
// Now kvp.Key is the date
// and kvp.Value is the count
}

Categories