I have a dataset that gets populated from a stored proc in sql server. I have a column that has lets say has a set of values. I do not know what those values are. All I know is that they of the type "string". I want to extract all the distinct values from that column.
You can use a DataView and set its RowFilter to the desired condition:
var view = new DataView(dataset.Tables["Table"]);
view.RowFilter = "Column = 42";
UPDATE: based on your updated question, you can use LINQ:
var table = dataset.Tables["Table"].AsEnumerable();
var distinctValuesForColumn =
table.Select(row => (string)row["Column"]).Distinct();
You can simply use Select method of the DataTable :
DataRow[] extractedRows =
yourDataSet.Tables["YourTableName"].Select("YourColumnName = 123");
You can also use Linq to query your datatables. Here is a link to some examples on the MS site - http://msdn.microsoft.com/en-us/vbasic/bb688086.aspx
I hope below statement will serve your purpose
ds.Tables["TableName"].DefaultView.ToTable( true, "columnName"); //For Dataset (true means distinct)
OR
`ds.Tables[0].DefaultView.ToTable( true, "columnName");
//For Dataset where tableindex is 0
OR
dt.DefaultView.ToTable( true, "columnName"); //For Datatable
//Syntax is like Datatable.DefaultView.ToTable( Distinct true/false, “ColumnName”);
MSDN : http://msdn.microsoft.com/en-us/library/wec2b2e6.aspx
Related
I have a dataTable with 4 columns ,
I want to select one column without foreach or any other expensive loop and my result must be a new data table with one column ,How can I do this;
DataTable leaveTypesPerPersonnel = LeaveGroup.GetLeaveTypesPerPersonnels(dtPersonnel.row);
leaveTypesPerPersonnel has this columns :
[ID,Guid,LeaveTypeID,Code]
I want Filter leaveTypesPerPersonnel wihtout foreach and get new datatable with just Column [ID]
NOTE: Output must be a Datatable With one column.
leaveTypesPerPersonnel.Columns.Remove("Guid");
leaveTypesPerPersonnel.Columns.Remove("LeaveTypeID");
leaveTypesPerPersonnel.Columns.Remove("Code");
or
DataTable dt= new DataView(leaveTypesPerPersonnel).ToTable(false,"ID");
You should be able to run a quick LINQ statement against the data table.
var results = (from item in leaveTypesPerPersonnel
select item.ID);
This will give you an IEnumerable if I remember correctly. It's not a DataTable, but might provide a solution to your problem as well.
Here is a try on how to search and convert the result to DataTable
var dataTable = leaveTypesPerPersonnel.Rows.Cast<DataRow>().ToList().Where(x=> x["ID"] == 21).CopyToDataTable().DefaultView.ToTable(false, "ID");
Or
var dataTable = leaveTypesPerPersonnel.Select("ID = 21").CopyToDataTable().DefaultView.ToTable(false, "ID");
Or
var dataTable = leaveTypesPerPersonnel.Rows.Cast<DataRow>().ToList().CopyToDataTable().DefaultView.ToTable(false, "ID");
I have a DataTable (Ado.Net) with column 'Status'. This column holds the values (in each records)
['Red','Green','Blue','Yellow','White','OtherColors']
I want to select all the rows which status value not Red,Green,Blue
What the kind of filter expression to use to select data with my proposed criteria. So i want to achive some thing like we used in sql query ( WHERE Status NOT IN ('Red','Green','Blue')
NB:This project is running .NET 2.0 i cant use linq
I have tested it, it works as desired:
DataRow[] filtered = tblStatus.Select("Status NOT IN ('Red','Green','Blue')");
The resulting DataRow[] contains only DataRows with OtherColors, Yellow and White.
If you could use LINQ i'd prefer that:
string[] excludeStatus = {"Red","Green","Blue"};
var filteredRows = tblStatus.AsEnumerable()
.Where(row => !excludeStatus.Contains(row.Field<string>("Status")));
Without Linq you can use the rowfilter of a DataView like this
public DataTable GetFilteredData(DataTable table, string[] filterValues)
{
var dv = new DataView(table);
var filter = string.join("','", filterValues);
dv.RowFilter = "Status NOT IN ('" + filter + "')";
return dv.ToTable();
}
Supposing your datatable is part of a typed dataset you can use Linq to datasets, from which you could something like:
var records =
from record in datatable
where !record.Status.Contains('Red','Green','Blue')
select record;
Even if you don't have a typed dataset Linq to datasets is your answer. You would need to some casting, but not to difficult.
I am trying to perform a two-pass search against a Sharepoint list. In the first pass, I am using a KeywordQuery to search against the index of all the items. In the second pass, I am applying column value filters chosen by a user by building a select statement.
ResultTableCollection rtc = kwqry.Execute();
ResultTable rt = rtc[ResultType.RelevantResults];
dt = new DataTable();
//Load Data Table
dt.Load(rt, LoadOption.OverwriteChanges);
DataRow[] rows = dt.Select("ColumnName1 = 'foo' AND ColumnName2 = 'bar'");
Where the columns could be multi-value lookup columns in a Sharepoint list. The first pass is working properly and returning the right number of matches in a DataTable. However, when I try to apply the Select statement, I get the following error: Cannot perform '=' operation on System.String[] and System.String. Converting the columns to a string instead of a string array results in the same error, as does using the IN operator.
Am I building my select statement incorrectly? How could I run my second pass filter on my DataTable?
Have you tried with LINQ?
DataTable t1 = new DataTable();
var rows = from x in t1.AsEnumerable()
where x.Field<string[]>("column1name").Contains("foo")
select x;
You have to specify the field type in the Where clause...
Hope it helps.
Try using this, it will work :
DataRow[] rows = dt.Select("(ColumnName1 = 'foo' AND ColumnName2 = 'bar')");
I have a DataTable named dt2 with data. I am calling its Select method to get some specific rows.
DataRow[] foundRows;
expression = "parent_id=1";
foundRows = dt2.Select(expression);
How can I pass the Select-method result to a new DataTable – say FilteredData?
You can use CopyToDataTable, available on IEnumerable<DataRow> types.
var filteredData = dt2.Select(expression).CopyToDataTable();
Just for clarity, the Select method returns an array of type DataRow. That's why we need to use CopyToDataTable(). Alex's answer is good. However, if the Select didn't return any rows, CopyToDataTable() will throw an InvalidOperationException.
So test that there is at least one DataRow before using the CopyToDataTable().
var filteredDataRows = dt2.Select(expression);
var filteredDataTable = new DataTable();
if(filteredDataRows.Length != 0)
filteredDataTable = filteredDataRows.CopyToDataTable();
Why not use a DataView instead?
DataView view = new DataView(dt2);
view.RowFilter = "parent_id = 1";
DataView will behave in very much the same way that a DataTable would with the added benefit that any change(s) to the underlying DataTable (dt2 in this case) would be automatically reflected in the DataView.
I'm trying to narrow down the rows that are in my DataView based on a relation with another table, and the RowFilter I'm using is as follows;
dv = new DataView(myDS.myTable,
"id IN (SELECT DISTINCT parentID FROM myOtherTable)",
"name asc",
DataViewRowState.CurrentRows);
"myTable" and "myOther" table are related via myTable.ID and myOtherTable.parentID, and so the idea is that the DataView should only contain rows from "myTable" which have corresponding child rows in "myOtherTable".
Unfortunately, I'm getting this error;
Syntax error: Missing operand after
'DISTINCT' operator.
The SQL is fine as far as I am aware, so I'm wondering is there some limitation on using the DISTINCT keyword as part of RowFilter's SQL? Anyone have any idea?
Unfortunately, I don't think you can perform a subquery in a DataView's filter expression. You're only allowed to use a subset of SQL in some expressions (documented here).
You'll probably need to perform your subquery (SELECT DISTINCT parentID FROM myOtherTable) separately.
This article describes the problem and a possible solution.
Unfortunately you can't do it that way, as the RowFilter property does not support the distinct keyword. Here is the list of expressions you can perform in a RowFilter (which is just a DataColumn Expression): http://msdn.microsoft.com/en-us/library/system.data.datacolumn.expression.aspx
DataViews have a ToTable method, and several overloads take a boolean to specify whether to return only the distinct rows.
Here is one method: http://msdn.microsoft.com/en-us/library/wec2b2e6.aspx
Here is how you would use it:
DataTable newDataTable = myDataView.ToTable( true, [array of column names as strings] );
DataView dvBindAssignedByDropDown = new DataView();
DataTable dtBindAssignedByDropDown = new DataTable();
dvBindAssignedByDropDown = ds.Tables[0].DefaultView;
string[] strColnames=new string[2];
strColnames[0] = "RedNames";
strColnames[1] = "RedValues";
dtBindAssignedByDropDown = dvBindAssignedByDropDown.ToTable(true, strColnames);
ddlAssignedby.DataTextField = "RedNamesNames";
ddlAssignedby.DataValueField = "RedNames";
ddlAssignedby.DataSource = dtBindAssignedByDropDown;
ddlAssignedby.DataBind();
ddlAssignedby.Items.Insert(0, "Assigned By");
ddlAssignedby.Items[0].Value = "0";
the following code is extracting distinct values/records from a table/dataview, namely(PROD_DESP_TRN) having field(CONTAINER_NO)
Finally, this code is filling a combobox(cmbContainerNo) with unique values/records
Form Level Declaration:
Dim dsLocal As DataSet
Dim dvm As DataViewManager
Private Sub FillcomboContainer()
Try
Dim dv As DataView = New DataView
cmbContainerNo.DataSource = Nothing
dv = dvm.CreateDataView(dsLocal.Tables("PROD_DESP_TRN"))
dv.Sort = "CONTAINER_NO"
cmbContainerNo.DataSource = dv.ToTable(True, "CONTAINER_NO")
cmbContainerNo.DisplayMember = "CONTAINER_NO"
Catch ex As Exception
MsgBox(ex.Message)
Finally
End Try
End Sub
Try just leaving out the "DISTINCT". In this case, the results should be the same with or without. Troubleshoot from there.