Reputation: 553
I currently have an object model using Entity Framework that contains a complex object with a property that is a list. I store it in the DB with the second option proposed here: Representing a list in a SQL database
But to summarize:
Person()
{
long Id;//primary key
string Name;
List<long> ResponsibleFor; //list of id
}
gets stored as the 2 following tables
Persons:
Id,
Name
Responsibilities:
Id,
PersonId,
ResponsibleForId
Now I'm kind of stumped with how to repopulate the Person object. My Current approach is the following:
from p in db.Persons
join r in db.Responsibilities on p.Id equals r.PersonId
where p.Id == IdImSearchingFor
select new Person
{
Id = p.Id
ResponsibileFor = ?
}
And I'm stuck trying to repopulate that List property.
Any Suggestions?
Thanks!
Upvotes: 1
Views: 2095
Reputation: 1910
My suggestion would be to use a Lazy load pattern for getting your list and it would probably perform and scale better. Using your example.
public class Person()
{
public long Id { get; set; }
public string Name { get; set;}
private Lazy<List<long>> _responsibleFor;
public List<long> ResponsibleFor
{
get { return _responsibleFor.Value; }
}
public void SetResponsibleFor(Func<long, List<long>> getResponsibleFor)
{
_responsibleFor = new Lazy<List<long>>( () => getResponsibleFor(Id) );
}
public Person():base() { }
public Person(long id, string name)
{
Id = id;
Name = name
}
}
// Implementation
var p = new Person(1,"John Doe");
p.SetResponsibleFor(GetResponsibleForPerson); //Pass a function/method which takes the long for input parameter and outputs List<long>
Upvotes: 0
Reputation: 2416
You need to group the result of the join to get all people responsible for.
Try
var result = from p in db.Persons
join r in db.Responsibilities on p.Id equals r.PersonId
where p.Id == IdImSearchingFor
group r.ResponsibleForId by p into g
select new Person
{
Id = g.Key.Id,
Name = g.Key.Name,
ResponsibleFor = g.ToList()
};
Upvotes: 2
Reputation: 553
Although everyone's previous answers helped me (Thank you!), they weren't completely working. So I thought I'd add my solution here, which was to use a combination of joins, grouping, and nested selects.
from p in db.Persons
where p.Id == IdImSearchingFor
join r in db.Responsibilities on p.Id equals r.ParentId into pr
select new Person
{
Id = p.Id,
name = p.Name,
ResponsibleFor = ( from a in pr
where a.ParentId == IdImSearchingFor
select new Person
{
Id = a.Id
}).ToList<Person>()
}
Upvotes: 0
Reputation: 5201
Check this one out. I have tested it will normal classes and Lists and not with EF or any other ORM.
The following is the class structure I have understood
class Person
{
public long Id;//primary key
public string Name;
}
class Responsibility
{
public long Id;//primary key
public long PersonId;
public long ResponsibleForId;
}
The following are the 2 test lists
List<Person> Persons = new List<Person>() { new Person() { Id = 1, Name = "Samar" } };
List<Responsibility> Responsibilities = new List<Responsibility>() { new Responsibility() { Id = 1, PersonId = 1, ResponsibleForId = 1 }, new Responsibility() { Id = 2, PersonId = 1, ResponsibleForId = 2 } };
The following is the query
var allPeople = from p in Persons
join r in Responsibilities on p.Id equals r.PersonId into g
where p.Id == 1
select new
{
Id = p.Id,
ReponsibleFor = g.Select(x => x.ResponsibleForId).ToList()
};
Hope this is what you are looking for.
Upvotes: 0
Reputation: 11741
Suppose you want to get the person Id 1 then..
from p in db.Persons
join r in db.Responsibilities on p.Id equals r.PersonId
where p.Id == 1
select new Person
{
Id = p.Id
ResponsibileFor = p.ReponsibleFor
}
Upvotes: 0