Retrieving the row index of row pulled from datatable useing Linq - asp.net

I am using the following query to pull a row from a datatable in memory.
Dim results = _
From myRow In exceldt.AsEnumerable() _
Where myRow.Field(Of String)("Serial Number") = Row.Item("Serial Number") _
Select myRow
resultrow = results.CopyToDataTable.Rows(0)
I need to get the index of the resultrow when it was part of exceldt. I can't seem to find anything on this. Suggestions?

I don't work in VB.net so forgive my code but you can get the index of a projection with something along the lines of this:
Dim result = exceldt.AsEnumerable() .Select (Function(item, index) _
New With { .Index = index, .SerialNumber = item }).ToList
I can't provide much more with in VB but this quick example does work as a Console app. You can see how the select / projection captures the index and item. You will need to incorporate similar logic before filtering (where) you initial enumeration.
Dim names = {"Andy", "Tom", "Fred", "Sally"}
Dim results = names _
.Select(Function(item, index) New With {.Index = index, .Name = item}) _
.OrderBy(Function(item) item.Name)
For Each item In results
Console.WriteLine("{0} - {1}", item.Index, item.Name)
Next
results
0 - Andy
2 - Fred
3 - Sally
1 - Tom

This should do the trick
int index = exceldt.Rows.IndexOf(results);

Related

How to limit the number of rows to be read in a CSV file using CSVReader in ASP.NET

I am using a csvReader in order to retrieve data from a csv file. My csv file consists of 500elements and I only need the first 300. How do I limit my csvReader in order to return only 300 elements?
Dim PressureTable As DataTable = GetDataTabletFromCSVFile(BackUpDirDminus1)
Console.WriteLine("Rows count:" + PressureTable.Rows.Count.ToString)
Console.ReadLine()
Using CSVReader As New TextFieldParser(BackUpDirDminus1)
CSVReader.SetDelimiters(New String() {","})
CSVReader.HasFieldsEnclosedInQuotes = True
'read column names
Dim colFields As String() = CSVReader.ReadFields()
'For Each column As String In colFields
While Not CSVReader.EndOfData
Dim fieldData As String() = CSVReader.ReadFields()
'Making empty value as null
For i As Integer = 0 To fieldData.Length-1
If fieldData(i) = "" Then
fieldData(i) = Nothing
End If
Next
PressureTable.Rows.Add(fieldData)
End While
End Using
Please help. Thanks
I suppose there should be a method name "ReadNextRecord()", so your while loop should be like
While CSVReader.ReadNextRecord()
Declare a int k =0
and do k++
Once K++ reaches 300, then you can End While.

How to fill all textboxes after click on gridview by making classLibrary?

I want to make a class library containing classes for common tasks.
I made such a class that worked very well on some forms but it have some errors that I can't trace down.
This is my code and it does the following:
It accepts 3 parameters: form name, datagridview name and the textbox name prefixes.
It counts the datagrid columns
It takes the current row index
It makes the array with a length corresponding to the number of columns
It's looking in the form for all text boxes that have a name with prefix parameter + column name and set the value in it
Code:
Sub setRecordFieldToControl(ByVal root As Form, ByVal dgv As DataGridView, ByVal cntrlPreNam1 As String, ByVal cntrlPreNam2 As String)
Dim j, k, z As Integer
Dim s As String
z = dgv.ColumnCount
k = dgv.CurrentRow.Index
j = 0
Dim headTxt(z) As String
For indx = 0 To z - 1
headTxt(indx) = dgv.Columns(indx).HeaderText
Next
For Each i As Control In root.Controls
If TypeOf i Is MaskedTextBox Or TypeOf i Is ComboBox Then
For clm = 0 To z
If i.Name = cntrlPreNam1 & headTxt(clm) Or i.Name = cntrlPreNam1 & headTxt(clm) Then
s = (dgv.Rows(k).Cells(j).Value)
i.Text = s
' i.Text = dgv.Item(j, k).Value
j = j + 1
If j >= z Then
Exit For
End If
End If
Next
End If
Next
End Sub
My problem is: on some forms I got this error:
Index is out of range for line i.Text = s
The error does not show up when I put something else in my text box, the error only appears when I put the s in it.
The error is probably in the line
For clm = 0 To z
It should read
For clm = 0 To z - 1
The column indexes range from 0 .. number_of_columns - 1.
UPDATE
There are several problems with your code:
The logic seems wrong to me. You are looking for the column (clm) with the right name but then take the value of another column (j). Why?
The variable names are not speaking and are even misleading (e.g. i for a Control).
You have nested loops with an O(n^2) behavior. See Big O Notation.
I suggest rewriting it. Use a dictionary for the possible control names, that stores the corresponding column indexes by name. Dictionaries have a nearly constant access speed. In other words: Lookups are very fast.
Sub SetRecordFieldToControl(ByVal root As Form, ByVal dgv As DataGridView, _
ByVal cntrlPrefix1 As String, ByVal cntrlPrefix2 As String)
Dim currentRowIndex As Integer = dgv.CurrentRow.Index
Dim columnDict = New Dictionary(Of String, Integer)
For i As Integer = 0 To dgv.ColumnCount - 1
Dim headerText As String = dgv.Columns(i).HeaderText
columnDict.Add(cntrlPrefix1 & headerText, i)
columnDict.Add(cntrlPrefix2 & headerText, i)
Next
For Each cntrl As Control In root.Controls
If TypeOf cntrl Is MaskedTextBox Or TypeOf cntrl Is ComboBox Then
Dim columnIndex As Integer
If columnDict.TryGetValue(cntrl.Name, columnIndex) Then
Dim value As Object
value = dgv.Rows(currentRowIndex).Cells(columnIndex).Value
If Not value Is Nothing Then
cntrl.Text = value.ToString()
End If
End If
End If
Next
End Sub

Search for multiple keywords using LINQ vb

I have some existing code that I need to modify to search more than one keyword. (I am new to all this by the way)
Dim topics As IQueryable(Of Global.Platform.Core.Data.Topic) = _
From t In _db.Topics
Where t.IsActive = True And t.TopicTitle.Contains(criteria) And t.ForumID = 0 And Not t.TopicTitle.Contains("default") And t.Member.IsActive = True And t.IsActive = True
Order By t.DateCreated Descending
Select t
Take (take_x)
Return topics
How would i go about changing this so if I entered criteria "cat hair" it would do an OR search. so ...t.TopicTitle.Contains("cat") OR t.TopicTitle.Contains("hair") ....
Of course it would need to be dynamic.
I tried this but could not get it to work.
Dim criteriaArr As Array = criteria.Split(" ")
Dim new_criteria As String = " t.TopicTitle.Contains(" + criteriaArr(0) + ")"
If criteriaArr.Length > 1 Then
For Each item As String In criteriaArr
new_criteria += " Or t.TopicTitle.Contains(" + item + ")"
Next
End If
The idea was to split the spaces and keep appending to the where clause. I know in SQL this might have worked, but how would I go about in this scenario?
You can use a combination of .Any and .Contains:
var strings = new List<string> { "cat", "dog", "bill" };
using (var context = new MyEntities())
{
var matches = context.MyObject.Where(x => strings.Any(s => x.TopicTitle.Contains(s)));
}
VB:
Dim strings = {"cat", "dog", "bill"}
Using context = New MyEntities()
Dim matches = context.MyObject.Where(Function(x) strings.Any(Function(s) x.TopicTitle.Contains(s)))
End Using
This is taking the strings list of query words, and checking to see if there are any of them that the TopicTitle contains.
Sorry, that's in C#, but you can see how to do the lamda expression in the .Where. Just send in a List to your method that does the query, and you're good to go.
Assuming TopicTitle and the criteria are space delimited strings I would intersect the two collections and check if there were any matches.
Dim topics As IQueryable(Of Global.Platform.Core.Data.Topic) = _
From t In _db.Topics
Where t.IsActive = True And t.TopicTitle.Intersect(criteria).Any()
And t.ForumID = 0 And Not t.TopicTitle.Contains("default")
And t.Member.IsActive = True And t.IsActive = True
Order By t.DateCreated Descending
Select t
Take (take_x)
Return topics

Entity Framework Navigable Property Not Set to Instance of Object?

I have the following query:
Dim queryStudent = (From p In dbContext.Residents _
Where p.people_code_id = people_id _
Where p.year = year _
Where p.semester = semester _
Join b In dbContext.Buildings On p.building Equals b.id _
Join r In dbContext.Rooms On p.room Equals r.id
Select p, b, r)
I then attempt to pull the building and room for that individual like so:
room = queryStudent.FirstOrDefault.r.id
building = queryStudent.FirstOrDefault.b.id
But I receive an Object reference not set to an instance of an object error.
I tried doing something like
If IsNothing(queryStudent.FirstOrDefault.r.id) Then
room = ""
Else
room = queryStudent.FirstOrDefault.r.id
End If
But that still generates the same error.
Check if r is nothing instead of the id of r.
If IsNothing(queryStudent.FirstOrDefault.r) Then
room = ""
Else
room = queryStudent.FirstOrDefault.r.id
End If
I suspect queryStudent.FirstOrDefault is null. If you try to access a property of a null object, you get that exception. Try this approach:
If IsNothing(queryStudent.FirstOrDefault) Then
room = ""
Else If IsNothing(queryStudent.First.r) Then
room = ""
Else
room = queryStudent.FirstOrDefault.r.id
End If
In each case, you are checking that the object you are about to access is not null.

ASP.Net String Split not working

Here's my code
Dim RefsUpdate As String() = Session("Refs").Split("-"C)
Dim PaymentsPassedUpdate As String() = Session("PaymentsPassed").Split("-"C)
Dim x as Integer
For x = 1 to RefsUpdate.Length - 1
Dim LogData2 As sterm.markdata = New sterm.markdata()
Dim queryUpdatePaymentFlags as String = ("UPDATE OPENQUERY (db,'SELECT * FROM table WHERE ref = ''"+ RefsUpdate(x) +"'' AND bookno = ''"+ Session("number") +"'' ') SET alpaid = '"+PaymentsPassedUpdate(x) +"', paidfl = 'Y', amountdue = '0' ")
Dim drSetUpdatePaymentFlags As DataSet = Data.Blah(queryUpdatePaymentFlags)
Next
I don't get any errors for this but it doesn't seem to working as it should
I'm passing a bookingref like this AA123456 - BB123456 - CC123456 - etc and payment like this 50000 - 10000 - 30000 -
I basically need to update the db with the ref AA123456 so the alpaid field has 50000 in it.
Can't seem to get it to work
Any ideas?
Thanks
Jamie
I'm not sure what isn't working, but I can tell you that you are not going to process the last entry in your arrays. You are going from 1 to Length - 1, which is one short of the last index. Therefore, unless your input strings end with "-", you will miss the last one.
Your indexing problem mentioned by Mark is only one item, but it will cause an issue. I'd say looking at the base your problem stems from not having trimmed the strings. Your data base probably doesn't have spaces leading or trailing your data so you'll need to do something like:
Dim refsUpdateString as string = RefsUpdate(x).Trim()
Dim paymentsPassedUpdateString as string = PaymentsPassedUpdate(x).Trim()
...
Dim queryUpdatePaymentFlags as String = ("UPDATE OPENQUERY (db,'SELECT * FROM table WHERE ref = ''" & refsUpdateString & "'' AND bookno = ''" & Session("number") & "'' ') SET alpaid = '" & paymentsPassedUpdateString & "', paidfl = 'Y', amountdue = '0' ")
Also, I would recommend keeping with the VB way of concatenation and use the & character to do it.

Resources