Есть таблица Category
с pk idCategory
и внешним ключом с собственной ссылкой fiCategory
.Это означает, что категории являются «основными категориями», когда fiCategory is null
.Если fiCategory
ссылается на другую категорию, это подкатегория.Но также верно, что эта подкатегория также имеет 1-n подкатегорий (с fiCategory
связыванием с idCategory
).
Q: Как я могу получить списокосновных категорий, подкатегорий, «подкатегорий», ... и т. д.с LINQ?
Backgound :
Я использую типизированные DataSets для сравнения данных с Server1 / MySQL с данными с Server2 / MS SQL-Server.После нормализации и очистки (есть несколько несоответствий) я хочу импортировать новые данные в SQL-сервер.Прежде всего я должен импортировать основные категории, затем подкатегории и так далее.В противном случае SQL-сервер выдаст исключение ограничения, когда я попытаюсь вставить строку с внешним ключом в категорию, которая еще не вставлена.
Это таблицы (слева MySQL-источник, справа SQL-Таблица назначения сервера):
Здесь я получаю новые строки в MySQL, которых нет в SQL-Server:
src
и dest
набираются DataSets
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