DataTable Rows to single Row Using LINQ - c#

I have a single column with multiple rows in a DataTable, I want them In a single row, and dont want to loop through each row of data table,
Here is Sample Data Table
Results
-------
Clinet1
Clinet2
Clinet3
Clinet4
I want to get a string like
Clinet1,Clinet2,Clinet3,Clinet4 but using LINQ without for loop.
I tried code below but its not working for me
string Details = myDataTable.Rows
.Cast<DataRow>()
.Where(x => x["Results"].ToString();

Using LINQ:
string Details = myDataTable.Rows.Cast<DataRow>()
.Where(x => x["Results"] == UserName)
.Select(i => i.ToString()).Aggregate((i, j) => i + "," + j)

Use String.join for this.
string Details = String.join(",", myDataTable.Rows
.Cast<DataRow>()
.Where(x => x["Results"] == UserName).ToArray());

You can use AsEnumerable to return an IEnumerable<T> object, where the generic parameter T is DataRow and String.Join to join rows into a string like this;
string rows = string
.Join(",", myDataTable.AsEnumerable()
.Select(x => x["Results"]));

Related

Searching for multiple strings using single database query with entity framework and LINQ

Assuming I have a database table (aTable) with two columns
id : int
name: string
Requirements:
I want to retrieve entries where aTable.name is like a list of strings (stringsToSearchFor).
What I am doing:
Currently I am using the following approach
var result=new List<aTable>;
foreach (var aString in stringsToSearchFor)
{
var r = Context.Set<aTable>()
.Any(s => s.name.Contains(searchString))
.ToList();
res.AddRange(r);
}
return result.Distinct();
To optimize it I tried to change the code by eliminating the foreach, to be:
return Context.Set<aTable>()
.Any(s => stringsToSearchFor.Contains(s.name))
.Distinct()
.ToList();
However, this didn't provide the same results as the previous statement. I believe the first statement is correct.
My question: How can I search for multiple strings without creating N database queries (like the 2nd approach)?
Alternative solution: use the EF 6.2 Like:
.Where(x => stringsToSearchFor.Any(s => DbFunctions.Like(x.name, "%" + s + "%")))
Here's the documentation for DbFunctions.Like.
Something like this should work:
string[] stringsToSearchFor = new string[] { "text1", "text2" };
using (MyDbContext model = new MyDbContext())
{
var result = model.aTable
.Where(r => stringsToSearchFor.Any(s => r.name.Contains(s)))
.ToList();
}

c# linq add single quote before & after field values on datatable

i have data table. now, i am converting/export this data table to csv.
for that my code is:
var valueLines = dt.AsEnumerable()
.Select(row => string.Join(",", row.ItemArray));
Here, suppose my fields are **Name Number Rollname RollNumber**.
after this query fire. it convert like: **Name,Number,Rollname,RollNumber**
it's work. i am getting csv file perfect. but issue this.
suppose some filed value like: Roll,Number ...at that time. i am getting 2 fields/cell on csv....i am thinking to add ' before & after field values.
or any another way to skip issue?
CSV accepts items enclosed in double-quotes. You can put double-quotes around each item by modifying your code as follows:
var valueLines = dt.AsEnumerable()
.Select(row => string.Join(
","
, row.ItemArray.Select(s => s.ToString().IndexOf(',') < 0 ? s : string.Format("\"{0}\"", s))));
The above replaces row.ItemArray with a Select that checks each item for ',', and puts double-quotes around strings that have commas.
Yes, one way would be wrap the fields in quotes on use a different delimiter that is rare like ^.
var valueLines = dt.AsEnumerable()
.Select(row => string.Join(",", row.ItemArray
.Select(f => string.Format("\"{0}\"", f))));
or
var valueLines = dt.AsEnumerable()
.Select(row => string.Join("^", row.ItemArray));
In general you should use a CSV-reader instead of reading the strings and splitting them manually. They support quoting characters and many more features. I can recommend this:
http://www.codeproject.com/Articles/9258/A-Fast-CSV-Reader
This is easy, remember you can mix old school concatenation with linq:
var valueLine = (from row in dt.AsEnumerable()
select "'" + row.Field("field name") + "'").ToList();

Linq to Entity Select, Exclude 1st result row?

I have a Linq to Entity Select statement that is currently returning all rows from the database. Since the 1st row of data contains header information, is it possible to exclude the first row from the result set?
var surveyProgramType = surveyProgramTypeRepository
.Find()
.OrderBy(x => x.ProgramType);
use .Skip()
var surveyProgramType = surveyProgramTypeRepository
.Find()
.OrderBy(x => x.ProgramType)
.Skip(1);
var surveyProgramType = surveyProgramTypeRepository
.Find()
.OrderBy(x => x.ProgramType).Skip(1);

C#: only one typecast in linq?

I have a gridview and each row displays one instance of MyCustomType. The instance itself is stored in the Tag property of DataGridViewRow. Now I want to use linq to select certain rows, based on multiple criteria. This looks like this:
var rows = grid_series.Rows
.Cast<DataGridViewRow>()
.Where(x => ((MyCustomType)x).myProperty != string.Empty)
.Where(x => ((MyCustomType)x).myOtherProperty < 42);
But I really want to avoid to cast the Tag-object in every single where statement. Is there a way to cast the object only once and use repeatedly? I thought about using a select statement first. Then I do have to apply the cast only once, but then I'd have to "re-convert" each result back to DataGridViewRow which I don't think is possible.
What about selecting the Tag and do another Cast (or OfType<> of not all the rows contains MyCustomType) afterwards:
var rows = grid_series.Rows
.Cast<DataGridViewRow>().Select(r => r.Tag).Cast<MyCustomType>()
.Where(x => x.myProperty != string.Empty)
.Where(x => x.myOtherProperty < 42);
If you want IEnumerable<DataGridViewRow> you you can try:
var rows = grid_series.Rows
.Cast<DataGridViewRow>()
.Select(r => new { MyType = (MyCustomType)r.Tag, Row = r })
.Where(x => x.MyType.myProperty != string.Empty)
.Where(x => x.MyType.myOtherProperty < 42)
.Select(x => x.Row);

Querying A Datable Using Linq Returning Distinct Values

I am attempting to get distinct values from a datatable column. here is my code..
var sourceItems = ds.Tables[0].AsEnumerable()
.GroupBy(x => x.Field<string>("Source").ToString())
.Select(x => x.First());
ddlSource.DataSource = sourceItems;
ddlSource.DataBind();
This code is returning 4 rows of System.Data.DataRow as the values. I need the actual values stored in the rows not the row type. Also is this code a proper way to grab only distinct values in the column?
I would do something like this:
var sourceItems = ds.Tables[0].AsEnumerable()
.Select(x => x.Field<string>("Source"))
.Distinct()
.ToList();
Note that .ToList() can be skipped, but of course it depends on what the DataSource property of the ddlSource object is able to accept. If It's a winforms control I suspect ToList is necessary.
Your code does basically the same as this one, but you must change the last Select into Select(x => x.Key) to select the values that are used to group the rows, and not the first row.
Also your code has more overhead than using Distinct, since GroupBy creates subgroups of the original collection.
Why don't you use the .Distinct extension method?
ds.Tables[0].AsEnumerable()
.Select(x => x.Field<string>("Source").ToString())
.Distinct()
.FirstOrDefault();
How about
var sourceItems = ds.Tables[0].AsEnumerable()
.Select(x => x.Field<string>("Source"))
.Distinct()
.ToList();
ddlSource.DataSource = sourceItems;
ddlSource.DataBind();
(You don't need to call .ToString() on a string, so I've removed that.)

Categories