我需要像getUsers(列表ID)一样进行查询; 我需要通过id搜索,如果找到则返回列表中带有ID的用户,如果找不到则返回所有用户,或者如果找到则只返回一个用户。
如何撰写此查询?
这就是我的开始:
public List<User> getUsers (List<int> ids)
{
using(var uow = _repository.CreateUnitOfWork())
{
var u = uow.GetEntities<User>().Where(c => c.Id in ids);
if (u == null)
u.ToList();
}
}
答案 0 :(得分:2)
您的问题没有意义,因为函数的返回类型必须始终相同。它有时无法返回List
,其余时间无法返回User
。
我会建议这样的事情:
public IEnumerable<User> GetUsersByIdOrAllUsers(IEnumerable<int> ids)
{
using (var uow = _repository.CreateUnitOfWork())
{
var users = uow.GetEntities<User>();
if (users.Any(c => ids.Contains(c.ID)))
{
return users.Where(c => ids.Contains(c.ID));
}
return users;
}
}
然后,您可以测试您是否只找到一个用户:
var matchingUsers = GetUsersByIdOrAllUsers(ids);
if (matchingUsers.Any() && !matchingUsers.Skip(1).Any())
{
var singleUser = matchingUsers.Single();
// Do stuff with the single user...
}
请注意,使用IEnumerable
会使操作变得懒惰,因此效率更高。如果确实想要List
,请执行以下操作:
var matchingUsersList = matchingUsers.ToList()
答案 1 :(得分:2)
假设uow.GetEntities<User>()
返回IQueryable<User>
,当列表中有id的用户时,建议的解决方案涉及执行两个昂贵的IN (...)
SQL查询,同时构建并传递{{1} }列表两次到数据库 - 一个用于ids
,一个用于Any
。
我宁愿以不同的方式构建它。我将基于Where
使用Where
执行查询,并在内存中实现结果。然后我会在本地检查它是否包含数据,如果是,将返回结果,otherwice将执行第二个查询不带过滤器,这应该更有效率。
这样的事情:
ids.Contains
总而言之,您无法通过单个数据库查询执行所需操作。它需要执行至少两个查询,唯一的问题是使用最有效的方法。
答案 2 :(得分:1)
一种简单的方法是使用Join
public List<User> getUsers (List<int> ids)
{
using(var uow = _repository.CreateUnitOfWork())
{
var u = uow.GetEntities<User>()
.Join(ids,x=>x.Id,y=>y,(x,y)=>x).ToList();
if (u.Count==0)
return uow.GetEntities<User>().ToList()
return u;
}
}
答案 3 :(得分:0)
不确定是否有一种不那么繁琐的方式,但逻辑上可能是这样的?:
if (uow.GetEntities<User>().Any(u => ids.Contains(u.ID))
return uow.GetEntities<User>().Where(u => ids.Contains(u.ID)).ToList();
return uow.GetEntities<User>().ToList();
我在这里假设uow.GetEntities<User>()
只返回一个可查询对象,并且它本身不会从数据库中实现任何内容,或者会有任何显着的性能损失。如果情况并非如此,则可能需要将此操作的代码放在DAL的更深处。
答案 4 :(得分:0)
public IList<User> getUsers (List<int > ids = null)
{
var query = _repository.GetEntities<User>();
if (ids == null)
return query.ToList();
if (ids.Count()==1)
{
var singleUser = query.FirstOrDefault(user => ids.Contains(user.Id));
if (singleUser!= null)
return new List<User>{ singleUser; };
return new List<User>();
}
return query.Where(user => ids.Contains(user.Id)).ToList();
}