I am a beginner and learning LINQ in VB.Net. I have one table A with column
workID (PK) and idAccount.
And another table B with column
Bid(PK), BName and workID(FK) .
There is one to one relationship between table A and table B.
Now I want to put/copy both the table data to another table C which has column as
workID, idAccount, BName. But I don't know how to write a LINQ query and get both table data and put it in 3rd table. Please help me. I have tried below till now. Below is the code snippet of my project.
Public Function Hello(ByVal dt As A, ByVal dtm As B)
Dim dtReturn As New C
If dt IsNot Nothing AndAlso dt.Any Then
Dim row As WorkOrderRow `row corresponding to the C Table
For Each r In dt
row = dtReturn.NewWorkRow 'traversing the row
With row
.WorkID = r.WorkID
.idAccount = r.idAccount
End With
dtReturn.AddWorkOrderActivityRow(row)
Next
End If
End Function
its working totally fine but I need to put the data of B too. With above code I am able to copy only data of table A. Kindly guide me how should I write my LINQ query and traverse it.
I should be able to do something like
With row
.WorkID = x.WorkID
.idAccount = x.idAccount
.BName = x.BName
End With
x being the row generated by the query.
You probably would like to join the result of A and B first (sample here: https://msdn.microsoft.com/en-us/library/bb311040.aspx), then create rows of C. This is much easier.
Dim newCs = (From a In tableA
Join b In tableB On a.workID Equals b.workID
Select New TableC With {
.workID = a.workID,
.idAccount = a.idAccount,
.BName = b.BName
})
Related
I'm trying to put together a query (select preferably) in SQL server that works with a single table. Said table is derived from two sets of data. Records where SET = OLD represent old data, records where SET = NEW represent new data. My intention is as follows:
If record CODE = A, keep/include the record.
If record CODE = C, keep/include the record but delete/exclude the corresponding record from the old set under the same ACT value.
If record CODE = D, delete/exclude it along with its corresponding record from the old set under the same ACT value.
If CODE = '' (blank/null), keep the record but only if it exists in the OLD set (meaning their isn't a corresponding record from the new set with the same ACT value)
What the table looks like before logic is applied:
ACT|STATUS |CODE|SET|VALUE
222| | |OLD|1
333| | |OLD|2
444| | |OLD|3
111|ADDED |A |NEW|4
222|CHANGED|C |NEW|5
333|DELETED|D |NEW|6
What the table should look like after logic is applied (end result)
ACT|STATUS |CODE|SET|VALUE
444| | |OLD|3
111|ADDED |A |NEW|4
222|CHANGED|C |NEW|5
While I can probably put together a select query to achieve the end result above I doubt it will run efficiently as the table in question has millions of records. What is the best way to do this without taking a long time to obtain the end result?
Something like this. you will have to split your query and union.
--Old Dataset
SELECT O.*
FROM MyTable O
LEFT JOIN Mytable N ON O.ACT = N.ACT AND N.[SET] = 'NEW'
WHERE O.[SET] ='OLD'
AND ISNULL(N.CODE,'A') = 'A'
UNION
-- New records
SELECT N.*
FROM MyTable N
WHERE N.[SET] ='NEW'
AND CODE <> 'D'
I am working in VB.NET. I have two datatables (table & table2), which are identical. The two columns in question are:
id | voided_id
1 | null
2 | null
3 | 2
table1 is the list of items, and table2 is the list of voided items. so, if an item has voided an earlier item, I want to exclude the voided item. In this example id 2 would be excluded because it was voided by id 3.
Here is what I have so far:
Dim compareResults = From table In resultOds
Group Join table2 In voidOds
On table.Field(Of Int64)("id") Equals table2.Field(Of Int64?)("voided_loan_id")
Into tablesJoin = Group From tableJoin In tablesJoin.Where(Function(x) x.Field(Of Int64?)("voided_loan_id") Is Nothing).DefaultIfEmpty()
Select table
right now, I get everything. The WHERE clause inside the group join isn't working. Any suggestions?
Many articles I found said .DefaultIfEmpty() should provide the functionality of the WHERE but this returns everything as well:
Dim compareResults2 = From table In resultOds
Group Join table2 In voidOds
On table.Field(Of Int64)("id") Equals table2.Field(Of Int64?)("voided_loan_id") Into tablesJoin = Group
From table2 In tablesJoin.DefaultIfEmpty()
Select table
based on some off-line input I got, I rewrote this as a subquery. Still returns everything.
Dim compareResults2 = From r In resultOds
Where Not (From v In voidOds Where v.Field(Of Int64?)("voided_loan_id") IsNot Nothing Select v.Field(Of Int64?)("voided_loan_id")).Contains(r.Field(Of Int64?)("id"))
Select r
Try below
C#
var s =ItemTable.Where(i=>!VoidedItem.Any(v=>v.id==i.id))?.ToList();
VB
Dim s = ItemTable.Where(Function(i) Not VoidedItem.Any(Function(v) v.id = i.id))?.ToList()
I didn't get it working so I defaulted to executing a SQL string. thanks for the feedback.
This might seem like a noob question, but here's the thing:
In the image, the first table name is facturaDetalle and the second one's facturamaster
I want to SUM all the total matching idfactura in facturadetalle and save them into the total column in the facturamaster table.
I'm working on a master-detail form in ASP.NET
UPDATE m
SET total = (SELECT SUM(d.total) FROM dbo.facturadetalle d WHERE d.idfactura = m.idfactura)
FROM dbo.facturamaster m
--WHERE m.total IS NULL
You can use UPDATE statement to do that.
UPDATE m
SET TOTAL = SUM(d.Total)
FROM idfactura AS m
INNER JOIN idfacturaldetelle AS d
ON m.idfactura = d.idfactura
I am having a bit of trouble, probably from my understanding of SQL. Here is the SQL I am currently using:
CREATE TEMPORARY TABLE Temp
(
sPropertyCode VARCHAR(9),
sDataDate DATE,
PRIMARY KEY (sPropertyCode)
);
INSERT IGNORE Temp (sPropertyCode, sDataDate)
SELECT sPropertyCode, sDataDate
FROM tasks as t, task_data AS d
WHERE t.iTaskId = d.iTaskId
AND iRemoved = 1
AND sDataType = 'sAgencyAgreementDate'
AND iBusinessStreamId = 9;
SELECT t.sPropertyCode, sDataDate, SFirstSeen, sTaskType
FROM tasks AS t, temp AS a
WHERE iRemoved = 1
AND iBusinessStreamId = 9
AND sTaskType IN ('RF', 'IF', 'CM')
AND t.sPropertyCode = a.sPropertyCode
ORDER BY sPropertyCode, sFirstSeen;
DROP TABLE Temp;
So the references 'RF', 'IF' and 'CM' are tasks that we receive. Each propertycode can touch each of these tasks once, and only once. I would like to show the date that each one of these was touched by the propertycode. It is working at the moment but it is showing it in three columns with the tasks types in one column. I would like each task to show in a seperate column with the date it was first seen in its own corresponding column.
So from the picture below is how it is currently laid out with the code above.
And here is how I would like it to look, instead of the tasks showing down the side, I would like them to show accross in columns with their own specific dates
Thank you in advance :)
SELECT t.sPropertyCode, sDataDate, SFirstSeen, a1.sTaskType, a2.sTaskType, a3.sTaskType
FROM tasks AS t
INNER JOIN temp AS a1 on t.sPropertyCode = a1.sPropertyCode and a1.sTaskType = 'RF'
INNER JOIN temp as a2 on t.sPropertyCode = a2.sPropertyCode and a2.sTaskType = 'IF'
INNER JOIN temp as a3 on t.sPropertyCode = a3.sPropertyCode and a3.sTaskType = 'CM'
WHERE iRemoved = 1 AND iBusinessStreamId = 9
ORDER BY sPropertyCode, sFirstSeen;
You can also user outer join if not always have all 3 tast type.
What is the difference in meaning between the CM,IF and RF columns for any row in your 5-col table ? They're always the very same value in the example you listed.
I am reading 2 tables in T-SQL like so:
Select r.UID,c.Forename,c.Surname,c.DOB From c LEFT OUTER JOIN r on........
Then in VB.NET I loop through the dataset like so:
For Each drR In dsR.Tables(0).Rows......Next
However when I test like so:
If Convert.IsDBNull(drR("r.UID")) Then
Or
String.IsNullOrEmpty(drR("r.UID"))
Convert.IsDBNull(r.UID))
I crash with
Column 'UID' does not belong to table
row
when the second table r has no record.
I did try both r.UID and UID.
To recoup: All is fine when I have a record in the second table, but what must I do when I do not? How do I test for DBNull so as not to crash with "Column .... does not belong to table row"?
P.S. Regardng the 2 answers below: I have to test for UID so as to know whether there is a record in the 2nd table or not.
You need to do a few thing to get your code flying.
First consider side stepping your problem by using an INNER JOIN instead of the LEFT OUTER JOIN.
OR Split the problem and work with two sets.
A set with UIDs:
select r.Uid, c.Forename, c.Surname, c.DOB
from c
inner join r
on c.forename=r.forename and c.surname=r.surname
A set without UIDs:
select c.Forename, c.Surname, c.DOB
from c
left outer join r
on c.forename=r.forename and c.surname=r.surname
where r.Uid is null
But if you need to do it in one go with all the rows from the LEFT Table then you will need to check for DBNull and here is how to do that:
If Not IsDBNull(drR("UID")) Then
'Success
Debug.Print(drR("UID"))
Else
'Failure
End If
This is another way to do the same check:
If Not TypeOf drR("UID") Is DBNull Then
'Success
Debug.Print(drR("UID"))
Else
'Failure
End If
also if you are in a long tight loop you may gain performance by indexing the column:
Dim dt as DataTable = DAL.GetYourDataTable()
Dim ixUID As Integer = dt.Columns.IndexOf("UID")
For Each dr As DataRow In dt.Rows
If Not IsDBNull(dr(ixUID)) Then
'Success
Debug.Print(dr(ixUID))
Else
'Failure
End If
Next
change your query to:
Select isnull(r.UID,''),c.Forename,c.Surname,c.DOB From c LEFT OUTER JOIN r on
You could use the AS alias to specify the column name if needed combined with lvo's suggestion
SELECT ISNULL(r.UID,'') AS 'UID' ...etc...
In that way the column has a name and therefore would eliminate the test for checking the column name UID if it is present on another table.
Hope this helps,
Best regards,
Tom.
Put a break after the dataset is filled. Then in your watch window add the following to see what the column name is (assuming r.UID is the first column then columns(0) )
- i.e. columns(columnnumber - 1)
dsR.Tables(0).columns(0).ColumnName