linq with dataTable in c# - c#

I am using datatable on which I want to use Linq. but as i am new to linq i dont know how it uses.
I google it I got lots of information which is not sufficient like. If I am using datatable and i got info like :
DataRow r = from dr in ds.Tables["Customers"].AsEnumerable()
where dr.Field<Guid>("customerid").ToString() = row[2].ToString()
select dr;
dt.ImportRow(r);
and I have lots of queries like what is "dr".
dr.fields?,
".AsEnumerable()" is not present at my side.
Even this code also doesnt work:
IEnumerable<DataRow> r = from dr in ds.Tables["Customers"].Select().Where(x => x.Field<Guid>("customerid").ToString() == row[2].ToString())
select dr;
So can anyone please give me link on which i got all information from beggining on linq.

You should iterate rows to achive it
var r = ds.Tables["Customers"].Rows
.Cast<DataRow>()
.Where(r => r["fieldName"].ToString() == "Test");

Hope this can help you.
LINQ to DataSet
http://msdn.microsoft.com/en-us/library/bb386921.aspx

It's like a SQL select query, where dr is the * (that is, it is the returned data).
Some nice examples: http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b

Related

Update query's where clause values from a datatable

I have this query:
UPDATE A
Set A.NUM = B.NUM
FROM A
JOIN B on A.ID = B.ID
where A.Code in ()
A.Code values are from a datatable. How do I feed into this query?
Why not write a code to make a comma separated string of ID's using datatable?
string lstOfIDs = string.Empty;
DataTable dt = new DataTable();
foreach (DataRow drow in dt.Rows)
{
lstOfIDs += drow["IdColumnHere"].ToString()+",";
}
lstOfIDs.TrimEnd(',');
You can then pass the lstOfIds in the IN clause.
EDIT 1:
I think A.Code In () is checking for code not Ids. I hope you are placing codes in the lstOfIDs. Also, I would advise putting ' between Id's. i.e.
lstOfIDs += "'"+drow["IdColumnHere"].ToString()+"',";
this should give you something like 'abc','def','anything'
You want a Table-Valued Parameter.
This article will also help:
http://www.brentozar.com/archive/2014/02/using-sql-servers-table-valued-parameters/
If you have more columns than just Code in the C# Datatable, you may also need a projection (inside the sql) get output that will work with the IN() clause. Something like this:
UPDATE A
Set A.NUM = B.NUM
FROM A
JOIN B on A.ID = B.ID
where A.Code in ( SELECT Code FROM #tvpCodes )

LINQ Select From DataTable

Just started to play around with datatable and LINQ today.
I have a datatable that gets a list of Names From SQL database.
I am looking to return a specific name from the dt using LINQ.
I have tried the following code with no success at this. Is there something that i am doing wrong with the code.
dt returns a full list of names i am just looking to reduce the names down to one name. There is a name in the adventureworks database called Blade i am trying to display this only.
DataTable dt = DAL.GetNames();
try
{
var q = from myrow in dt.AsEnumerable()
where myrow.Field<string>("Name") =="Blade"
select myrow;
dataGridView1.DataSource = q;
}
I have tried to replace the == with a .equals.
I am totally new to the concept of using a Language intergrated query.
when i run the code noting happens i dont get any errors ect just no data returned.
You're defining your query but not actually running it.
Your line:
dataGridView1.DataSource = q;
Needs to be:
dataGridView1.DataSource = q.AsDataView();

filter datatable on loop

Is there anyway of filtering datatable based on other datatable. something like below:
foreach (datarow dr in somedatatable.select("id= someothertable.rows["someotherid"])
{
dr[somefield]=someothertable[someotherfield];
}
You can do a ordinary SQL select using DataView
DataView dv = new DataView(dataTableToFilter);
dv.RowFilter = ""//SQL condition
Complete useful example in your case you can find here:
Creating a DataTable from a DataView
Where you apply a DataView filter to a DataTable and create a new DataTable from filtered rows.
I have a question, why you want to do the filter logic in your code? Your example logic is very simple.
I order to do filter more efficient, we'd like use database to do that. I think your requirement can be implemented by using a join statement. Do you agree?

Data table select top 5 rows

Hi is there any way to select top 5 rows from a data table without iteration?
I think, You can use LINQ:
datatable.AsEnumerable().Take(5);
Using 2 of the above posts, the following works for me:
foreach (DataRow _dr in DataSet.Tables[<tblname>].Select("", "Timestamp DESC").AsEnumerable().OfType<DataRow>().Take(5))
So now you can normally filter if you want, order if you want and then get only the amount of records that you want and then iterate through them whether it is 1 or 100.
Hope that helps someone.
This is what worked for me:
datatable.Rows.Cast<System.Data.DataRow>().Take(5);
This works for my needs.
public static DataTable TopRows(this DataTable dTable, int rowCount)
{
DataTable dtNew = dTable.Clone();
dtNew.BeginLoadData();
if (rowCount > dTable.Rows.Count) { rowCount = dTable.Rows.Count; }
for (int i = 0; i < rowCount;i++)
{
DataRow drNew = dtNew.NewRow();
drNew.ItemArray = dTable.Rows[i].ItemArray;
dtNew.Rows.Add(drNew);
}
dtNew.EndLoadData();
return dtNew;
}
to use it you then do this:
dataTable.TopRows(5);
If you use a LINQ statement, you could use the Take() method.
This post may be of some assistance as well.
EDIT
As you are using VS2005, use the SELECT() method in the datatable like so:
DataRow[] rows = datatable.Select('TOP 5');

Using Linq to filter a ComboBox.DataSource?

in another topic, I've stumbled over this very elegant solution by Darin Dimitrov to filter the DataSource of one ComboBox with the selection of another ComboBox:
how to filter combobox in combobox using c#
combo2.DataSource = ((IEnumerable<string>)c.DataSource)
.Where(x => x == (string)combo1.SelectedValue);
I would like to do a similar thing, but intead of filtering by a second combobox, I would like to filter by the text of a TextBox. (Basically, instead of choosing from a second ComboBox, the user simply enters his filter in to a TextBox). However, it turned out to be not as straight forward as I had hoped it would be. I tried stuff as the following, but failed miserably:
cbWohndresse.DataSource = ((IEnumerable<DataSet>)ds)
.Where(x => x.Tables["Adresse"].Select("AdrLabel LIKE '%TEST%'"));
cbWohndresse.DisplayMember = "Adresse.AdrLabel";
cbWohndresse.ValueMember = "Adresse.adress_id";
ds is the DataSet which I would like to use as filtered DataSource.
"Adresse" is one DataTable in this DataSet. It contains a DataColumn "AdrLabel". Now I would like to display only those "AdrLabel", which contain the string from the user input. (Currently, %TEST% replaces the textbox.text.)
The above code fails because the lambda expression does not return Bool. But I am sure, there are also other problems (which type should I use for IEnumerable? Now it's DataSet, but Darin used String. But how could I convert a DataSet to a string?
Yes, I am as much newbyish as it gets, my experience is "void", and publicly so. So please forgive me my rather stupid questions.
Your help is greatly appreciated, because I can't solve this on my own (tried hard already).
Thank you very much!
Pesche
P.S. I am only using Linq to achieve an uncomplicated filter for the ComboBox (avoiding a View). The rest is not based on Linq, but on oldstyle Ado.NET (ds is filled by an SqlDataAdapter), if that's of any importance.
LINQ does not seem, to me, like an obvious solution here. Your data is already loaded into a DataSet structure, so you should be able to do something like this:
var adresse = ds.Tables["Adresse"];
adresse.DefaultView.RowFilter = "AdrLabel LIKE '%TEST%'";
cbWohndresse.DataSource = adresse;
cbWohndresse.DisplayMember = "AdrLabel";
cbWohndresse.ValueMember = "adress_id"
cbWohndresse.DataBind();
To address the actual problems in your current code:
If ds is of type DataSet, casting it to IEnumerable<DataSet> will fail.
DataTable.Select returns an array of rows, not a boolean.
Ignoring #1 and #2, your Where() call would return zero, one or more DataSet instances which each have a table named "Adresse" with at least one row matching the filter. Hence, you end up binding your presentational control to a set of DataSet instances, which is not what you need.
If you want to use LINQ, then you'll need to add a reference System.Data.DataSetExtensions. You can then query your DataSet in a "linqish" manner.
The blog post Querying DataSets – Introduction to LINQ to DataSet by Erick Thompson, a PM at Microsoft is a good introduction to LINQ to DataSets
Here's a very crude example:
XAML
<StackPanel>
<TextBox x:Name="MyFilter" />
<ComboBox x:Name="MyComboBox"
ItemsSource="{Binding}"
DisplayMemberPath="AdrLabel" />
<Button Click="OnFilterClick">Filter</Button>
</StackPanel>
Code Behind
public partial class FilteredDataSet : Window
{
public FilteredDataSet()
{
InitializeComponent();
CreateDataContext();
MyComboBox.DataContext = MyDataSet.Tables[0];
}
private DataSet MyDataSet { get; set; }
private void CreateDataContext()
{
var ds = new DataSet();
var dt = new DataTable( "Adresse" );
ds.Tables.Add( dt );
var dc = new DataColumn( "AdrLabel" );
dt.Columns.Add( dc );
DataRow dr = dt.NewRow();
dr[0] = "one";
dt.Rows.Add( dr );
dr = dt.NewRow();
dr[0] = "honed";
dt.Rows.Add( dr );
dr = dt.NewRow();
dr[0] = "obiwone";
dt.Rows.Add( dr );
dr = dt.NewRow();
dr[0] = "won";
dt.Rows.Add( dr );
MyDataSet = ds;
}
private void OnFilterClick( object sender, RoutedEventArgs e )
{
string filter = MyFilter.Text;
var context = MyDataSet.Tables[0].AsEnumerable()
.Where( dr => dr.Field<string>( "AdrLabel" ).Contains( filter ) )
.Select( dr => dr.Field<string>( "AdrLabel" ) );
MyComboBox.DisplayMemberPath = string.Empty;
MyComboBox.DataContext = context;
}
}

Categories

Resources