有一个Category
带有 pkidCategory
和自引用外键的表fiCategory
。这意味着当 fiCategory is null
. 如果fiCategory
链接到另一个类别,它是它的子类别。但是这个子类别也有 1-n 个子类别(fiCategory
链接到它idCategory
)也是有效的。
问:如何获取主类别、子类别、子类别、...等的列表。与 LINQ?
背景:
我正在使用类型化的数据集来比较来自 Server1/MySQL 的数据和来自 Server2/MS SQL-Server 的数据。规范化和清理后(有几个不一致的地方)我想将新数据导入 SQL-Server。首先我必须导入主要类别,然后是子类别等等。否则,当我尝试将具有外键的行插入尚未插入的类别时,SQL-Server 将引发约束异常。
这些是表(左 MySQL 源表,右 SQL Server 目标表):
在这里,我得到了 MySQL 中不在 SQL-Server 中的新行:
src
并且dest
是类型化的数据集
Dim idSrc = From c In src.kategorie Select c.kategorie_id
Dim idDest = From c In dest.Category Select c.idCategory
Dim diff = idSrc.Except(idDest)
Dim needUpdate = diff.Any
现在我想导入新行。通过这种方式,我得到了所有“主要类别”:
Dim mainCat = From kat In src.kategorie
Join d In diff
On kat.kategorie_id Equals d
Where kat.IsparentNull
Select kat
For Each cat In mainCat
Dim newCat = Me.dest.Category.NewCategoryRow
newCat.idCategory = cat.kategorie_id
newCat.Name = cat.name
newCat.SetfiCategoryNull()
dest.Category.AddCategoryRow(newCat)
rowsUpdated += daCategoryOut.Update(dest.Category)
Next
通过这种方式,我得到了所有子类别:
Dim subCat = From kat In src.kategorie
Join d In diff
On kat.kategorie_id Equals d
Where Not kat.IsparentNull
Select kat
两个 LINQ 查询都在工作,但我如何获得子类别的所有“级别”?我需要将行从“顶部”插入到“底部”。有没有一种方法可以在任何深度下都有效?
至少这不起作用(重复 pk 值):
Dim subCatWithChild = From cat In subCat
Join child In
(From kat In src.kategorie Where Not kat.IsparentNull)
On child.parent Equals cat.kategorie_id
Select cat
我仍在学习 LINQ 并欣赏任何类型的建议(也在 C# 中)。先感谢您。
注意:也许您知道一种方法,我可以暂时禁用 SQL-Server 中的外键约束,并在我从 ADO.NET 插入所有行后启用它。那会简单得多。
这是解决方案,感谢@Tridus:
Dim mainCat = From kat In src.kategorie
Where kat.IsparentNull
Select kat
For Each kat In mainCat
rowsUpdated += insertCategory(kat, diff, daCategoryOut)
Next
这是递归函数:
Private Function insertCategory(ByVal parent As CC_IN.kategorieRow, ByVal diff As IEnumerable(Of Int32), ByVal daCategoryOut As CC_OutTableAdapters.CategoryTableAdapter) As Int32
Dim rowsInserted As Int32 = 0
If diff.Contains(parent.kategorie_id) Then
Dim newCat = Me.dest.Category.NewCategoryRow
newCat.idCategory = parent.kategorie_id
newCat.Name = parent.name
If parent.IsparentNull Then
newCat.fiCategory = parent.parent
Else
newCat.SetfiCategoryNull()
End If
dest.Category.AddCategoryRow(newCat)
rowsInserted += daCategoryOut.Update(dest.Category)
End If
'get all childs from this parent
Dim childs = From cat In Me.src.kategorie
Where Not cat.IsparentNull AndAlso cat.parent = parent.kategorie_id
Select cat
'insert all childs for this parent
For Each child In childs
rowsInserted += insertCategory(child, diff, daCategoryOut)
Next
Return rowsInserted
End Function