I have 3 tables :
- USERS_TABLE(userid, name)
- ACTIVITY_HISTORY_TABLE(userid, datefrom,dateto,activityId)
- ACTIVITY_TABLE (activityId, name)
In EF these are the below entities coresponding to the tables
- User(UserId,Name, AssignedActivities) AssignedActivities beeing the navigation property
- ActivityHistory (UserId, DateFrom,DateTo,activityId,TheActivity) TheActivity being the navigation property
- Activity (ActivityId, Name)
I need to return a List with all my users including the activities they are doing at the time of the requests (ActivityHistory.Datefrom <= now and ActivityHistory.DateTo >= now).
Users with no current activity are also to be returned.
Users that have multiple activities must not be duplicated
I need "User.AssignedActivities" and "ActivityHistory.TheActivity" to be loaded (no lazy loading).
So far I have 4 solutions that all fail one of my needs
1 - Only returns users that have activities at the given time and not all of the users
public List<User> GetAll()
{
using (Entities _db = new Entities())
{
return _db.USERS_TABLE
.Include("ActivityHistory")
.Include("ActivityHistory.Activity")
.Where(x => x.ActivityHistory.Any(y => y.DateFrom <= DateTime.Now && y.DateTo >= DateTime.Now))
.ToList();
}
}
2 - Returns the correct list of Users (complete with no duplicates) but activities are not loaded (System.ObjectDisposedException when manipulating User.AssignedActivities in the returned list)
(solution seen here : EF Query With Conditional Include)
public List<User> GetAll()
{
using (Entities _db = new Entities())
{
var query = from users in _db.USERS_TABLE
select new
{
users,
assignments = from ActivityAssigned in users.AssignedActivities
.Where(y => y.DateFrom <= now && y.DateTo >= now)
.DefaultIfEmpty()
select ActivityAssigned
};
var query2 = query
.AsEnumerable()
.Select(x => x.users);
return query2.ToList();
}
}
3 - Returns duplicates when users have many activities and the activies are not loaded (System.ObjectDisposedException when manipulating User.AssignedActivities in the returned list)
(Solution from Steve Ruble here below)
public List<User> GetAll()
{
using (Entities _db = new Entities())
{
var query =
from u in _db.USERS_TABLE
select new {
User = u,
CurrentActivities = u.ActivityHistory
.Where(y =>
y.DateFrom <= DateTime.Now
&& y.DateTo >= DateTime.Now)
.Select(ah => new
{
ActivityHistory = ah,
Activity = ah.Activity
}
}
return query.AsEnumerable().Select(x=> x.User).ToList();
}
}
4 - Does what I want but takes forever to do it, using the repository of the ActivityHistory entity:
public List<User> GetAll()
{
using (Entities _db = new Entities())
{
List<Users> MyUsersList = new List<Users>();
MyUsersList = _db.USERS_TABLE
.Include("ActivityHistory")
.Include("ActivityHistory.Activity")
.ToList();
for (int i = 0; i < MyUsersList.Count(); i++)
{
List<ActivityHistory > UserCurrentActivityList = new List<ActivityHistory >();
ActivityListRepository activityListRepo = new ActivityListRepository();
UserCurrentActivityList = activityListRepo.GetUserCurrentActivity(MyUsersList[i].UserId);
MyUsersList[i].AssignedActivities = UserCurrentActivityList;
}
return MyUsersList;
}
}
Help :) !