Pregunta

Tengo una tabla de autorreferencia con un Id, CategoryName y ParentId. Es un escenario típico de una tabla jerárquica de categorías que se pueden dividir en categorías que los expertos de DB me dicen que se llama modelo de adyacencia.

Lo que quiero es usar Linq to SQL para consultar las subcategorías que no están relacionadas con ninguna otra subcategoría, es decir, son nodos hoja inmediatos de alguna categoría o subcategoría determinada.

La parte fácil, que obtuve, es solo obtener las subcategorías. Casi avergonzado de poner el código aquí. Pero nos gusta ver el código ...

IList<Categories> subcategories = context.Where( c => c.ParentId == 1).ToList();  

Pero reducirlo a categorías sin subcategorías me está cambiando. Cualquier ayuda sería muy apreciada.

Gracias por tu ayuda. Jeff

ACTUALIZACIÓN ** Parece que esto funciona, pero si alguien pudiera confirmar que es " correcto " Estaria agradecido. Entonces, si quiero nodos de hoja en una categoría con Id = 1, haría esto:

Categories.Where( c => !c.Children.Any ( d => d.ParentId == c.Id)).Where( e => e.ParentId == 1) 

" Niños " es el nombre que Linq le da a la asociación de autorreferencia.

¿Fue útil?

Solución

Su solución es correcta porque el método Any () se traduce en sql " EXISTS () " función y ! c.Children.Any (d = > d.ParentId == c.Id)) se traduce en una cláusula de SQL similar a NOT EXISTS (SELECT * FROM Categories WHERE ParentID = outerRef .ID)

Otra forma de hacerlo es usar Count :

Categories.Where( c => c.Children.Count(d => d.ParentId == c.Id) == 0).Where( e => e.ParentId == 1)

Pero generalmente se prefiere EXISTS () a COUNT () en sql (por razones de rendimiento), por lo que la solución con Any () debe ser la correcta.

Otros consejos

Creo que si entiendo su pregunta correctamente, está intentando obtener todos los elementos secundarios que no tienen hijos propios ... esta consulta se une a la tabla en sí misma para probar si el nodo se usa como padre , si no lo es, entonces se muestra en el resultado.

No estoy seguro de si esto funciona ya que no tengo nada para probarlo en ...

   (from c in context
    join cc in context on c.id equals cc.parentid into temp
    from t in temp.DefaultIfEmpty()
    where t == null
    select c).ToList()
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top