我有3张桌子:
在EF中,这些是与表相对应的以下实体
我需要返回一个包含所有用户的List,包括他们在请求时所做的活动(ActivityHistory.Datefrom< = now和ActivityHistory.DateTo> = now)。
也不会返回没有当前活动的用户。
不得复制具有多项活动的用户
我需要加载“User.AssignedActivities”和“ActivityHistory.TheActivity”(没有延迟加载)。
到目前为止,我有4个解决方案都无法满足我的需求
1 - 仅返回在给定时间而不是所有用户都有活动的用户
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 - 返回正确的用户列表(完整且没有重复)但未加载活动(在返回列表中操作User.AssignedActivities时出现System.ObjectDisposedException)
(此处见解决方案: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 - 当用户有许多活动并且未加载活动时返回重复项(在返回列表中操作User.AssignedActivities时出现System.ObjectDisposedException)
(Steve Ruble在下面的解决方案)
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 - 使用ActivityHistory实体的存储库,我想要的是,但需要永远这样做:
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;
}
}
帮助:)!
答案 0 :(得分:1)
_db.Database.EnableLazyLoading = false;
_db.Database.UseProxyObjects = false;
var now = DateTime.Now; //DON'T REFACTOR THIS LINE!!!
var query = from user in _db.USERS_TABLE
from activity in user.ACTIVITY_HISTORY
group activity by user into g
select new {
User = g.Key,
CurrentActivities = g.Where(activity =>
activity.DateFrom <= now && activity.DateTo >= now)
};
return query.ToList().Select(x => x.User).ToList();
编辑:修正......我希望。但是,我建议不要使用此查询。它非常hacky。我强调,如果你想查找CurrentActivities,我会使用数据结构来存储它。
这项工作的事实由EF如何工作的一些细微差别结合在一起。这是非常糟糕的做法,你最终会遇到很多问题。
答案 1 :(得分:1)
如果您想要的是所有用户的列表,并且每个用户都有当前活动或null ,则应该这样做。诀窍在于DefaultOrEmpty
,它在SQL端被转换为LEFT OUTER JOIN。
from u in _db.USERS_TABLE
from aht in u.ActivityHistory
.Where(y => y.DateFrom <= DateTime.Now && y.DateTo >= DateTime.Now)
.DefaultIfEmpty()
select new {
User = u,
CurrentActivityHistory = ah
CurrentActivity = ah.Activity
}
修改强>
如果你想要的是所有用户的列表,包含所有当前的ActivityHistory记录,以及为每个ActivityHistory急切加载的活动,你可以这样做:
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
}
}
关于具体化实体的说明:
考虑这个变量的值:
var record = query.First();
属性record.User.ActivityHistory
将使用与ActivityHistory
包含相同record.CurrentActivities
个对象的集合进行填充,即使用户中有更多非当前ActivityHistory
记录数据库。换句话说,如果您需要获取ActivityHistory
的{em> all User
条记录,则需要进行另一次查询,而不是依赖延迟加载来提取它们in。
答案 2 :(得分:1)
最后,在花了太多时间讨论这个问题之后,我终于找到了我的解决方案(我相信这种方式与关系修复概念有些接近,但我可能会说这里有荒谬之处。)
public List<User> GetAll()
{
using (Entities _db = new Entities())
{
_db.Configuration.LazyLoadingEnabled = false;
var now = DateTime.Now;
var currentActivities = _db.ActivityHistory
.Where(x => x.DateFrom <= now && x.DateTo >= now)
.Include("TheActivity")
.ToList();
var Controlers = _db.User.ToList();
return Controlers;
}
}
实际上答案一直是Here:
发出两个单独的查询:一个用于电影,一个用于评论,让关系修复完成剩下的工作。
任何评论赞赏的想法。 谢谢。