Reputation: 32072
I have a hierarchy like this:
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; }
}
To get a specific ThirdChild from an instance of BaseClass, I was trying with something like this:
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();
}
Is this the shortest/cleanest way of doing this? I would think there's an easier way, but I'm new to Entity Framework. I don't have any data to test this for now, since I'm still modelling it. The context class looks like this:
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; }
}
Upvotes: 1
Views: 128
Reputation: 33867
I think you might be going about this slightly backwards and your multiple 'FirstOrDefault' calls may cause you some performance issues, as each one will hit the DB.
Perhaps you need somthing more like:
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();
i.e. thinking similarly to how you would do this if you were writing SQL directly, select from ThirdChild, join up the hierarchy and filter in the where clause.
Note - this assumes a one-many relationship between each parent and its children.
Upvotes: 1
Reputation: 205849
You are defining one-to-many
relationships. You already provided so called navigation property at the one side, but you need also to provide the similar at the many side, like this
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; }
}
Then you can start the query directly from the level you want
context.Third.Where(t => t.Identifier == thirdIdentifier
&& t.Parent.MyProperty.Identifier == identifierReceived
&& t.Parent.Parent.SomeId == idReceived
&& t.Parent.Parent.Parent.username == username)
Upvotes: 1