2016-01-18 3 views
1

У меня есть иерархия, как это:Query 4-уровней вложенности списка иерархии

public class BaseClass 
{ 
    public virtual List<FirstChild> Childs { get; set; } 
} 
public class FirstChild 
{ 
    public virtual List<SecondChild> Childs { get; set; } 
} 
public class SecondChild 
{ 
    public virtual List<ThirdChild> Childs { get; set; } 
} 
public class ThirdChild 
{ 
    public List<FourthCild> Childs { get; set; } 
} 
public class FourthCild 
{ 
    public int SomeProperty { get; set; } 
} 

Чтобы получить конкретный ThirdChild из экземпляра BaseClass, я пытался что-то вроде этого:

using (MyDb context = new MyDb()) 
{ 
    context.BaseClass.Where(u => u.username == username).FirstOrDefault() 
    .FirstChild.Where(f => f.SomeId == idReceived).FirstOrDefault() 
    .SecondChild.Where(s => s.MyProperty.Identifier == identifierReceived).FirstOrDefault() 
    .ThirdChild.Where(t => t.Identifier == thirdIdentifier).FirstOrDefault(); 
} 

Это самый короткий/самый чистый способ сделать это? Я думаю, что есть более простой способ, но я новичок в Entity Framework. У меня нет данных, чтобы проверить это на данный момент, так как я все еще моделирую его. Класс контекста выглядит следующим образом:

public class MyDb: DbContext 
{ 
    public DbSet<BaseClass> Base { get; set; } 
    public DbSet<FirstChild> First { get; set; } 
    public DbSet<SecondChild> Second { get; set; } 
    public DbSet<ThirdChild> Third { get; set; } 
} 
+0

Определите и используйте свойство навигации Parent для каждого уровня. –

ответ

1

Вы определяете отношения one-to-many. Вы уже предоставили так называемый свойства навигации на стороне один, но вы должны также обеспечить подобные на многой стороны, как этот

public class BaseClass 
{ 
    public virtual List<FirstChild> Childs { get; set; } 
} 
public class FirstChild 
{ 
    public virtual BaseClass Parent { get; set; } 
    public virtual List<SecondChild> Childs { get; set; } 
} 
public class SecondChild 
{ 
    public virtual FirstChild Parent { get; set; } 
    public virtual List<ThirdChild> Childs { get; set; } 
} 
public class ThirdChild 
{ 
    public virtual SecondChild Parent { get; set; } 
    public List<FourthCild> Childs { get; set; } 
} 
public class FourthCild 
{ 
    public virtual ThirdChild Parent { get; set; } 
    public int SomeProperty { get; set; } 
} 

Затем вы можете запустить запрос напрямую от уровня вы хотите

context.Third.Where(t => t.Identifier == thirdIdentifier 
    && t.Parent.MyProperty.Identifier == identifierReceived 
    && t.Parent.Parent.SomeId == idReceived 
    && t.Parent.Parent.Parent.username == username) 
+0

Я выбираю ваш ответ, так как вы нашли время, чтобы объяснить код напрямую свойства навигации. –

1

Я думаю, вы могли бы идти об этом немного назад и ваши многочисленные вызовы «FirstOrDefault» может вызвать у вас некоторые проблемы с производительностью, так как каждый из них ударит БД.

Возможно, вам нужно Somthing больше как:

var target = (from tc in context.Third 
    where tc.Identifier == thirdIdentifier 
    && tc.SecondChild.MyProperty.Identifer == identifierReceived 
    && tc.SecondChild.FirstChild.someId == idReceived 
    && tc.SecondChild.FirstChild.Base.username == username 
    select tc).FirstOrDefault(); 

то думает так же, как вы бы это сделать, если вы пишете SQL непосредственно, выберите из ThirdChild, присоединиться к иерархии и фильтр, где положение.


Примечание - это предполагает отношения между несколькими родителями и его дочерними элементами.

+0

@Paddy Две из этих булевых проверок - это операторы присваивания в вашем примере. –

+0

Как я могу обратиться к второму ребенку с третьего ребенка? Использование свойства 'virtual ParentType'? –

+0

@ zackery.fix спасибо. Переключение между VB.net и C# сегодня. Постоянная ошибка при наборе текста ... – Paddy

Смежные вопросы