Background :
我将数据从MySQL数据库导入SQL-Server数据库(用于报告,后来用于SSAS-Cube) . 我想同时规范化数据 . 我想将 Ticket_IDs
重复分组到表 Contact
中的一条记录以及其他有用的信息,并将rawdata保留在子表 ContactDetail
中(将foreign键保留为Contact) . 因此 Contact
中的每条记录都有一个独特的 Ticket_ID
.
我决定使用强类型数据集进行导入 . 现在我想知道如果我已经添加了Ticket_ID,最好的方法是什么 . 我可以在每个循环(~100000条记录)中检查它,但我假设有更好/更快的方式 .
简化的样本数据:
Ticket_ID ID fiContact
89442226 1 1
89442226 2 1
89442226 3 1
89442261 4 2
89442261 5 2
89442354 6 3
89442359 7 4
89442359 8 4
89442367 9 5
89442504 10 6
这应该是 Contact
-table
Ticket_ID idContact
89442226 1
89442261 2
89442354 3
89442359 4
89442367 5
89442504 6
Question :
是否可以通过Ticket_ID对LINQ / LINQ-to-DataSet进行分组,并获取每个ContactRow的ContactDetailRows列表?我知道有一个GroupBy -Extension,但我不确定如何使用,如果它做我需要的(保持ContactDetail-Rows,f.e . 像一个dicitonary与Ticket_ID作为键和 List(of EmailRow)
作为值) .
这就是我所拥有的(简化):
For Each srcEmail In src.email 'i want to group src.email by Ticket_ID'
'so far i check for existence in every loop'
Dim res = From c In dest.Contact
Where c.Ticket_ID = srcEmail.ticket_id
If Not res.Any Then
'create new Contact
Dim newContact = Me.dest.Contact.NewContactRow
newContact.Ticket_ID = srcEmail.ticket_id
' ..... '
dest.Contact.AddContactRow(newContact)
End If
'TODO: create ContactDetail row and add it to the DataTable '
Next
-
src
:类型化数据集(MySQL) -
src.email
:键入DataTable =>进入ContactDetail
-
dest
:类型化数据集(SQL-Server) -
dest.Contact
键入的DataTable -
dest.ContactDetail
键入DataTable,其中fk为Contact
我更喜欢VB.NET,因为我还不熟悉LINQ,语法在C#中完全不同 .
Edit:
感谢@Magnus我通过以下方式实现:
Dim emailsPerTicketID = src.email.ToLookup(Function(email) email.ticket_id)
For Each ticket In emailsPerTicketID
'create new Contact
Dim newContact = Me.dest.Contact.NewContactRow
newContact.Ticket_ID = ticket.Key
newContact.CreatedAt = ticket.First().modified_time
' ...... '
dest.Contact.AddContactRow(newContact)
'TODO: add now all EmailRows'
For Each emailRow In ticket
Dim newContactDetail = dest.ContactDetail.NewContactDetailRow
newContactDetail.ContactRow = newContact
newContactDetail.Interaction = emailRow.interaction
' .... '
dest.ContactDetail.AddContactDetailRow(newContactDetail)
Next
Next
我将看一下,如果这比使用HashSet的迭代方法更快,以检测联系人是否已经创建 .
2 回答
我认为使用Lookup(就像一本字典但用密钥/ Collection代替)对你来说是一个很好的解决方案 . 这样的事情:
如果你需要任何帮助翻译任何语法到VB评论我 .
我的VB生锈了,但这里有一个镜头:
或者,如果您希望每次循环检查它,您可以使用HashSet,每次只是将票证ID添加到哈希集,然后通过
Contains
方法检查其存在 . 这比你正在做的要快,但我怀疑LINQ分组会比HashSet快 .