Using LINQ Datarow -> string instead of Datarow -> String[] -> String, - linq

I want to get a particular datacoulmn values into string by appending each row values.
I have a below code which will return into string array, and then i use foreach to append each string to one string
string[] strs = ds.Tables[0].AsEnumerable().Select(s => s.Field<string>("name")).ToArray<string>();
StringBuilder sb = new StringBuilder();
foreach(string str in strs)
{
sb.Append(str);
}
can this be replaced into LINQ query which will return result in string?

You can use String.Join to join these together directly, which also eliminates the need to create the temporary array:
var result = string.Join("", ds.Tables[0].AsEnumerable().Select(s => s.Field<string>("name")));

Related

Dictionary<string, List<Dictionary<string,string>>> query using linq

I have the below dictionary
Dictionary<string,string> q1=new Dictionary<string,string>
{
{"h1","name1"},{"h2","name2"}
};
Dictionary<string,string> q2=new Dictionary<string,string>
{
{"h1","name12"},{"h2","name23"}
};
Dictionary<string,string> q3=new Dictionary<string,string>
{
{"h1","name123"},{"h2","name234"}
};
List<Dictionary<string,string>> m1 = new List<Dictionary<string,string>> { q1,q2,q3 };
Dictionary<string, List<Dictionary<string,string>>> mhi = new Dictionary<string, List<Dictionary<string,string>>>();
mhi.Add("x1", m1);
I need to return a list which has the values name1,name12,name123 using linq.
I am aware of normal method which works for me. But I am curious to know how to implement this using linq
Try this:
var q1 = new Dictionary<string, string> {
{"h1", "name1"},
{"h2", "name2"}
};
var q2 = new Dictionary<string, string> {
{"h1", "name12"},
{"h2", "name23"}
};
var q3 = new Dictionary<string, string> {
{"h1", "name123"},
{"h2", "name234"}
};
var m1 = new List<Dictionary<string, string>> { q1, q2, q3 };
//Using LINQ
List<string> result = (from dictionary in m1
from keyValuePair in dictionary
where keyValuePair.Key == "h1"
select keyValuePair.Value).ToList();
//result = name1,name12,name123
//without linq
var result2 = new List<string>();
foreach(var dictionary in m1)
foreach(var keyValuePair in dictionary)
if(keyValuePair.Key == "h1")
result2.Add(keyValuePair.Value);
Edit:
The from clause specifies the data source, the where clause applies the filter, and the select clause projects each element of the sequence into a new form.
Linq queries are not executed until we iterate through it. (Here .ToList() is doing that). It's like a blueprint which specifies how the information is returned when executed(iterated).
Lets examine each statement separately:
from dictionary in m1 - This is much like foreach(var dictionary in m) except that it doesn't iterate (Because its a blueprint). It specifies which source we are iterating through (m1) and the variable to assign to each member (dictionary that is. We know that it will be of type Dictionary<String, String>)
from keyValuePair in dictionary - Here we use the dictionary variable created from the previous statement. The type of keyValuePair will be KeyValuePair<string,string> because we will be "iterating" through a Dictionary<string,string> when the query is executed.
where keyvaluePair.Key == "h1" - This filters out the keyValuePairs from the previous statement whose Key property equals "h1".
Now that we filtered out the KeyValuePairs, we can select their Value property. This "projects" the filtered out KeyValuePair sequence to the new type IEnumerable<string>
Finally, ToList method executes the query to get the results.

create extension method in linq

How to create an extension method to the string to get a sum
create Sumstring extension method
List<myclass> obj=new List<myclass>()
{
new myclass(){ID=1,name="ali",number=1},
new myclass(){ID=1,name="karimi",number=2},
new myclass(){ID=2,name="mohammad",number=4},
new myclass(){ID=2,name="sarbandi",number=5},
};
var query = (from p in obj
group p by p.ID into g
select new
{ id = g.Key, sum = g.Sumstring(p => p.name) }).ToList();
dataGridView1.DataSource=query;
I connect to the database
What is the code
You've not specified what SumString really returns, but looks like you're talking about string concatenation of all source collection elements.
It can be easily done using String.Join method:
public static class EnumerableOfString
{
public static string SumString<TSource>(this IEnumerable<TSource> source, Func<TSource, string> selector, string separator = null)
{
return String.Join(separator ?? string.Empty, source.Select(i => selector(i)));
}
}
That method allows following calls:
g.SumString(p => p.name)
with string.Empty as default deparator and with custom separator specified:
g.SumString(p => p.name, ",")
If all you want to do is concatenate the strings in that group you can use the built-in Aggregate function:
var query = (from p in obj
group p by p.ID into g
select new
{ id = g.Key, sum = g.Aggregate((tot, next) => tot + "," + next) }
).ToList();

Linq query Group By multiple columns

I have a array of string say:
String[] Fields=new String[]{RowField,RowField1}
In which I can use the below query to get the values by specifying the values is query i.e RowField and RowField1:
var Result = (
from x in _dataTable.AsEnumerable()
select new
{
Name = x.Field<object>(RowField),
Name1 = x.Field<object>(RowField1)
})
.Distinct();
But if suppose I have many values in the Array like:
String[] Fields= new String[]
{
RowField,
RowField1,
RowField2,
.......
RowField1000
};
How can I use the query here without specifying each of the rowfield in the query?
How can i iterate through the array items inside the LINQ?
According to some suggestions in LINQ query and Array of string I am trying to get the result using the code below.
var result = (from row in _dataTable.AsEnumerable()
let projection = from fieldName in fields
select new {Name = fieldName, Value = row[fieldName]}
select projection.ToDictionary(p=>p.Name,p=>p.Value))
.Distinct();
But the problem is it does not return the distinct values.Any ideas?
Start with distinct DataRows by using this overload of Distinct():
_dataTable.AsEnumerable().Distinct(new DataRowEqualityComparer())
Where DataRowEqualityComparer is:
public class DataRowEqualityComparer : IEqualityComparer<DataRow>
{
public bool Equals(DataRow x, DataRow y)
{
return x.ItemArray.SequenceEqual(y.ItemArray);
}
public int GetHashCode(DataRow obj)
{
return string.Join("", obj.ItemArray).GetHashCode();
}
}

linq select from database where ID in an ArrayList

I have an array-list that contains some UserID.
I need a query like this:
vat tmp= users.select(a=> a.UserID in (arraylist));
what can I do?
If it's actually in an ArrayList, you should create a List<T> or array first. Then you can use Contains:
// Use the appropriate type, of course.
var ids = arraylist.Cast<string>().ToList();
var tmp = users.Select(a => ids.Contains(a.UserID));
While using Contains on the plain ArrayList may well compile, I would expect it to fail at execution time, assuming users is an IQueryable<>.
List<long> list =new List<long>();
var selected = from n in users where list.Contains(n.ID) select n ;
OR
var selected = users.Where(a=> list.Contains(a.ID)).ToList();
This is the solution I used.
public static IEnumerable<SettingModel> GetSettingBySettingKeys(params string[] settingKey)
{
using (var db = new BoxCoreModelEntities())
{
foreach (var key in settingKey)
{
var key1 = key;
yield return Map(db.Settings.Where(s => s.SettingKey == key1).First());
}
}
}

GroupBy String and Count in LINQ

I have got a collection. The coll has strings:
Location="Theater=1, Name=regal, Area=Area1"
Location="Theater=34, Name=Karm, Area=Area4445"
and so on. I have to extract just the Name bit from the string. For example, here I have to extract the text 'regal' and group the query. Then display the result as
Name=regal Count 33
Name=Karm Count 22
I am struggling with the query:
Collection.Location.GroupBy(????);(what to add here)
Which is the most short and precise way to do it?
Yet another Linq + Regex approach:
string[] Location = {
"Theater=2, Name=regal, Area=Area1",
"Theater=2, Name=regal, Area=Area1",
"Theater=34, Name=Karm, Area=Area4445"
};
var test = Location.Select(
x => Regex.Match(x, "^.*Name=(.*),.*$")
.Groups[1].Value)
.GroupBy(x => x)
.Select(x=> new {Name = x.Key, Count = x.Count()});
Query result for tested strings
Once you've extracted the string, just group by it and count the results:
var query = from location in locations
let name = ExtractNameFromLocation(location)
group 1 by name in grouped
select new { Name=grouped.Key, Count=grouped.Count() };
That's not particularly efficient, however. It has to do all the grouping before it does any counting. Have a look at this VJ article for an extension method for LINQ to Objects,
and this one about Push LINQ which a somewhat different way of looking at LINQ.
EDIT: ExtractNameFromLocation would be the code taken from answers to your other question, e.g.
public static string ExtractNameFromLocation(string location)
{
var name = (from part in location.Split(',')
let pair = part.Split('=')
where pair[0].Trim() == "Name"
select pair[1].Trim()).FirstOrDefault();
return name;
}
Here is another LINQ alternative solution with a working example.
static void Main(string[] args)
{
System.Collections.Generic.List<string> l = new List<string>();
l.Add("Theater=1, Name=regal, Area=Area"); l.Add("Theater=34, Name=Karm, Area=Area4445");
foreach (IGrouping<string, string> g in l.GroupBy(r => extractName(r)))
{
Console.WriteLine( string.Format("Name= {0} Count {1}", g.Key, g.Count()) );
}
}
private static string extractName(string dirty)
{
System.Text.RegularExpressions.Match m =
System.Text.RegularExpressions.Regex.Match(
dirty, #"(?<=Name=)[a-zA-Z0-9_ ]+(?=,)");
return m.Success ? m.Value : "";
}

Resources