使用Linq和EF
一个User
可以包含多个RoleUserLinks
。
如果User
的{{1}}表包含2条记录,其中一条记录的RoleUserLink
为LinkStatusID
,另一条记录的Deleted
为LinkStatusID
1}},下面的查询返回Added
。我不想要这个。
如果有User
user
的{{1}} LinkStatusID
,请参阅下面的案例3,如何不返回Added
IEnumerable<User> z =
(from users in listOfUsersForReviewer
join roleUserLinks in context.RoleUserLinks
on users.UserID equals roleUserLinks.UserID into roleUserLinksJoin
// left join
from roleUserLinks in roleUserLinksJoin.DefaultIfEmpty()
where
// case 1 - has never been added to a role ie record isn't there
roleUserLinks.LinkStatus == null
// case 2 - has been soft deleted from a role so we want this record
|| roleUserLinks.LinkStatusID == (byte)Enums.LinkStatus.Deleted
select users).Distinct();
案例1)用户没有关联的RoleUserLink
记录。用户按预期返回
案例2)用户有1个关联的RoleUserLink
记录,其中LinkStatusID
已删除。用户按预期返回
案例3)用户有2个关联的RoleUserLink
条记录。 1的已删除LinkStatusID
。用户不应该被退回
答案 0 :(得分:1)
如果我理解得很好,那应该是:
IEnumerable<User> z =
(from users in listOfUsersForReviewer
join roleUserLinks in context.RoleUserLinks
on users.UserID equals roleUserLinks.UserID into roleUserLinksJoin
// left join
from roleUserLinks in roleUserLinksJoin.DefaultIfEmpty()
where
(roleUserLinks == null
|| roleUserLinks.LinkStatusID == (byte)Enums.LinkStatus.Deleted)
&& !roleUserLinksJoin.Where(x=> roleUserLinks.LinkStatusID == (byte)Enums.LinkStatus.Added && x.UserID == roleUserLinks.UserID).Any()
select users).Distinct();
我添加了这个子查询:
&& !roleUserLinksJoin.Where(x=> roleUserLinks.LinkStatusID == (byte)Enums.LinkStatus.Added && x.UserID == roleUserLinks.UserID).Any()
它会从RoleUserLinks
中有LinkStatusId
Added
的记录的用户中删除不需要的行。
我还将此roleUserLinks.LinkStatus == null
更改为roleUserLinks == null
以避免NullReferenceException
,以防RoleUserLink
User
我测试代码的示例代码
static void Main(string[] args)
{
var usersList = new List<User>()
{
new User() {UserID = 1},
new User() {UserID = 2},
new User() {UserID = 3}
};
var userLinksList = new List<RoleUserLink>()
{
new RoleUserLink() {UserID = 1, State = "del"},
new RoleUserLink() {UserID = 2, State = "add"},
new RoleUserLink() {UserID = 2, State = "del"}
};
IEnumerable<User> z = (from users in usersList
join roleUserLinks in userLinksList
on users.UserID equals roleUserLinks.UserID into roleUserLinksJoin
// left join
from roleUserLinks in roleUserLinksJoin.DefaultIfEmpty()
where
// has never been added to a role ie record isn't there
roleUserLinks == null
// has been soft deleted from a role so we want this record
|| roleUserLinks.State == "del"
// has been added to role so we don't want this record
&& !roleUserLinksJoin.Where(x=> x.State == "add" && x.UserID == roleUserLinks.UserID).Any()
select users).Distinct();
var res = z.ToList();
}
public class User
{
public int UserID { get; set; }
}
public class RoleUserLink
{
public int UserID { get; set; }
public string State { get; set; }
}
它返回id为1和3的用户。正如我所料。 UserId:1
仅与状态delete
相关联。 UserId:3
没有任何链接。并且未返回UserId:2
,因为它还与状态add
相关联。
答案 1 :(得分:0)
我通过采用原始查询解决了这个问题:
IEnumerable<User> z =
(from users in listOfUsersForReviewer
join roleUserLinks in context.RoleUserLinks
on users.UserID equals roleUserLinks.UserID into roleUserLinksJoin
// left join
from roleUserLinks in roleUserLinksJoin.DefaultIfEmpty()
where
// case 1 - has never been added to a role ie record isn't there
roleUserLinks.LinkStatus == null
// case 2 - has been soft deleted from a role so we want this record
|| roleUserLinks.LinkStatusID == (byte)Enums.LinkStatus.Deleted
select users).Distinct().Include(b => b.RoleUserLinks).ToList();
并在最后添加了Include和ToList。
然后:
var list = new List<User>();
foreach (var user in z)
{
bool shouldReturnUser = true;
//get roleLinks
foreach (var rul in user.RoleUserLinks)
{
if (rul.LinkStatusID == (byte) Enums.LinkStatus.Added)
shouldReturnUser = false;
}
if (shouldReturnUser)
list.Add(user);
}
然后返回此列表。
据我所知,通过这样做,并在网络服务器上进行处理有一个打击,但恕我直言这很容易理解,它的工作原理: - )